- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 43 43 #include "qpaintengineex_opengl2_p.h" 44 44 45 #if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) 46 #include "private/qeglcontext_p.h" 47 #endif 48 45 49 QT_BEGIN_NAMESPACE 46 50 … … 50 54 51 55 QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix) 52 : Q TextureGlyphCache(type, matrix)53 , ctx( context)56 : QImageTextureGlyphCache(type, matrix) 57 , ctx(0) 54 58 , m_width(0) 55 59 , m_height(0) 56 { 57 glGenFramebuffers(1, &m_fbo); 60 , m_filterMode(Nearest) 61 { 62 setContext(context); 63 } 64 65 void QGLTextureGlyphCache::setContext(QGLContext *context) 66 { 67 ctx = context; 68 69 // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where 70 // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The 71 // workaround is to use a system-memory copy of the glyph cache for this device. 72 // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and 73 // be slower, so that is not desireable. 74 if (!ctx->d_ptr->workaround_brokenFBOReadBack) 75 glGenFramebuffers(1, &m_fbo); 76 58 77 connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), 59 78 SLOT(contextDestroyed(const QGLContext*))); 60 79 } 61 80 62 QGLTextureGlyphCache::~QGLTextureGlyphCache() 81 void QGLTextureGlyphCache::clear() 63 82 { 64 83 if (ctx) { 65 84 QGLShareContextScope scope(ctx); 66 glDeleteFramebuffers(1, &m_fbo);67 85 68 86 if (m_width || m_height) 69 87 glDeleteTextures(1, &m_texture); 70 } 88 89 m_texture = 0; 90 m_width = 0; 91 m_height = 0; 92 m_w = 0; 93 m_h = 0; 94 m_cx = 0; 95 m_cy = 0; 96 m_currentRowHeight = 0; 97 coords.clear(); 98 } 99 100 } 101 102 QGLTextureGlyphCache::~QGLTextureGlyphCache() 103 { 104 if (ctx) { 105 QGLShareContextScope scope(ctx); 106 107 if (!ctx->d_ptr->workaround_brokenFBOReadBack) 108 glDeleteFramebuffers(1, &m_fbo); 109 } 110 111 clear(); 71 112 } 72 113 73 114 void QGLTextureGlyphCache::createTextureData(int width, int height) 74 115 { 116 // create in QImageTextureGlyphCache baseclass is meant to be called 117 // only to create the initial image and does not preserve the content, 118 // so we don't call when this function is called from resize. 119 if (ctx->d_ptr->workaround_brokenFBOReadBack && image().isNull()) 120 QImageTextureGlyphCache::createTextureData(width, height); 121 122 // Make the lower glyph texture size 16 x 16. 123 if (width < 16) 124 width = 16; 125 if (height < 16) 126 height = 16; 127 75 128 glGenTextures(1, &m_texture); 76 129 glBindTexture(GL_TEXTURE_2D, m_texture); … … 79 132 m_height = height; 80 133 81 QVarLengthArray<uchar> data(width * height); 82 for (int i = 0; i < data.size(); ++i) 83 data[i] = 0; 84 85 if (m_type == QFontEngineGlyphCache::Raster_RGBMask) 86 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); 87 else 134 if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { 135 QVarLengthArray<uchar> data(width * height * 4); 136 for (int i = 0; i < data.size(); ++i) 137 data[i] = 0; 138 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 139 } else { 140 QVarLengthArray<uchar> data(width * height); 141 for (int i = 0; i < data.size(); ++i) 142 data[i] = 0; 88 143 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); 144 } 89 145 90 146 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 91 147 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 148 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 149 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 150 m_filterMode = Nearest; 92 151 } 93 152 94 153 void QGLTextureGlyphCache::resizeTextureData(int width, int height) 95 154 { 155 int oldWidth = m_width; 156 int oldHeight = m_height; 157 158 // Make the lower glyph texture size 16 x 16. 159 if (width < 16) 160 width = 16; 161 if (height < 16) 162 height = 16; 163 164 GLuint oldTexture = m_texture; 165 createTextureData(width, height); 166 167 if (ctx->d_ptr->workaround_brokenFBOReadBack) { 168 QImageTextureGlyphCache::resizeTextureData(width, height); 169 Q_ASSERT(image().depth() == 8); 170 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); 171 glDeleteTextures(1, &oldTexture); 172 return; 173 } 174 96 175 // ### the QTextureGlyphCache API needs to be reworked to allow 97 176 // ### resizeTextureData to fail 98 99 int oldWidth = m_width;100 int oldHeight = m_height;101 102 GLuint oldTexture = m_texture;103 createTextureData(width, height);104 177 105 178 glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); … … 114 187 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 115 188 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 189 m_filterMode = Nearest; 116 190 glBindTexture(GL_TEXTURE_2D, 0); 117 191 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, … … 160 234 glBindTexture(GL_TEXTURE_2D, m_texture); 161 235 162 #ifdef QT_OPENGL_ES_2163 QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);164 buffer.resize(4*oldWidth*oldHeight);165 glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());166 167 // do an in-place conversion from GL_RGBA to GL_ALPHA168 for (int i=0; i<oldWidth*oldHeight; ++i)169 buffer.data()[i] = buffer.at(4*i + 3);170 171 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,172 GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());173 #else174 236 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); 175 #endif176 237 177 238 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, … … 188 249 void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) 189 250 { 251 if (ctx->d_ptr->workaround_brokenFBOReadBack) { 252 QImageTextureGlyphCache::fillTexture(c, glyph); 253 254 glBindTexture(GL_TEXTURE_2D, m_texture); 255 const QImage &texture = image(); 256 const uchar *bits = texture.constBits(); 257 bits += c.y * texture.bytesPerLine() + c.x; 258 for (int i=0; i<c.h; ++i) { 259 glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); 260 bits += texture.bytesPerLine(); 261 } 262 263 return; 264 } 265 190 266 QImage mask = textureMapForGlyph(glyph); 191 267 const int maskWidth = mask.width(); … … 218 294 glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); 219 295 } else { 220 #ifdef QT_OPENGL_ES2221 glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());222 #else223 296 // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is 224 297 // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista … … 232 305 for (int i = 0; i < maskHeight; ++i) 233 306 glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); 234 #endif 235 } 236 } 237 238 int QGLTextureGlyphCache::glyphMargin() const 239 { 240 #if defined(Q_WS_MAC) 241 return 2; 242 #elif defined (Q_WS_X11) 243 return 0; 244 #else 245 return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; 246 #endif 247 } 248 307 } 308 } 309 310 int QGLTextureGlyphCache::glyphPadding() const 311 { 312 return 1; 313 } 314 315 int QGLTextureGlyphCache::maxTextureWidth() const 316 { 317 return ctx->d_ptr->maxTextureSize(); 318 } 319 320 int QGLTextureGlyphCache::maxTextureHeight() const 321 { 322 if (ctx->d_ptr->workaround_brokenTexSubImage) 323 return qMin(1024, ctx->d_ptr->maxTextureSize()); 324 else 325 return ctx->d_ptr->maxTextureSize(); 326 } 249 327 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.