Changeset 846 for trunk/src/opengl
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 69 edited
- 5 copied
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/qgl2pexvertexarray.cpp
r651 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) … … 62 62 } 63 63 64 void QGL2PEXVertexArray::addRect(const QRectF &rect)65 {66 vertexArray << rect.topLeft() << rect.topRight() << rect.bottomRight()67 << rect.bottomRight() << rect.bottomLeft() << rect.topLeft();68 }69 70 64 void QGL2PEXVertexArray::addClosingLine(int index) 71 65 { 72 if (QPointF(vertexArray.at(index)) != QPointF(vertexArray.last())) 73 vertexArray.add(vertexArray.at(index)); 66 QPointF point(vertexArray.at(index)); 67 if (point != QPointF(vertexArray.last())) 68 vertexArray.add(point); 74 69 } 75 70 … … 146 141 int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); 147 142 if (threshold < 3) threshold = 3; 148 qreal one_over_threshold_minus_1 = 1.f/ (threshold - 1);143 qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1); 149 144 for (int t=0; t<threshold; ++t) { 150 145 QPointF pt = b.pointAt(t * one_over_threshold_minus_1); -
trunk/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
r651 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) … … 94 94 GLfloat bottom; 95 95 96 operator QRectF() {return QRectF(left, top, right-left, bottom-top);}96 operator QRectF() const {return QRectF(left, top, right-left, bottom-top);} 97 97 }; 98 98 … … 101 101 public: 102 102 QGL2PEXVertexArray() : 103 vertexArray(0), vertexArrayStops(0), 103 104 maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10), 104 boundingRectDirty(true) {} 105 boundingRectDirty(true) 106 { } 107 108 inline void addRect(const QRectF &rect) 109 { 110 qreal top = rect.top(); 111 qreal left = rect.left(); 112 qreal bottom = rect.bottom(); 113 qreal right = rect.right(); 114 115 vertexArray << QGLPoint(left, top) 116 << QGLPoint(right, top) 117 << QGLPoint(right, bottom) 118 << QGLPoint(right, bottom) 119 << QGLPoint(left, bottom) 120 << QGLPoint(left, top); 121 } 105 122 106 void addRect(const QRectF &rect); 123 inline void addQuad(const QRectF &rect) 124 { 125 qreal top = rect.top(); 126 qreal left = rect.left(); 127 qreal bottom = rect.bottom(); 128 qreal right = rect.right(); 129 130 vertexArray << QGLPoint(left, top) 131 << QGLPoint(right, top) 132 << QGLPoint(left, bottom) 133 << QGLPoint(right, bottom); 134 135 } 136 137 inline void addVertex(const GLfloat x, const GLfloat y) 138 { 139 vertexArray.add(QGLPoint(x, y)); 140 } 141 107 142 void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true); 108 143 void clear(); -
trunk/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp
r651 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) -
trunk/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
r651 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) -
trunk/src/opengl/gl2paintengineex/qglengineshadermanager.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) … … 42 42 #include "qglengineshadermanager_p.h" 43 43 #include "qglengineshadersource_p.h" 44 #include "qpaintengineex_opengl2_p.h" 44 45 45 46 #if defined(QT_DEBUG) … … 97 98 code[UntransformedPositionVertexShader] = qglslUntransformedPositionVertexShader; 98 99 code[PositionOnlyVertexShader] = qglslPositionOnlyVertexShader; 100 code[ComplexGeometryPositionOnlyVertexShader] = qglslComplexGeometryPositionOnlyVertexShader; 99 101 code[PositionWithPatternBrushVertexShader] = qglslPositionWithPatternBrushVertexShader; 100 102 code[PositionWithLinearGradientBrushVertexShader] = qglslPositionWithLinearGradientBrushVertexShader; … … 248 250 249 251 // The address returned here will only be valid until next time this function is called. 252 // The program is return bound. 250 253 QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog) 251 254 { … … 255 258 // Move the program to the top of the list as a poor-man's cache algo 256 259 cachedPrograms.move(i, 0); 260 cachedProg->program->bind(); 257 261 return cachedProg; 258 262 } … … 330 334 if (newProg->useOpacityAttribute) 331 335 newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); 332 if (newProg->usePmvMatrix ) {336 if (newProg->usePmvMatrixAttribute) { 333 337 newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); 334 338 newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); … … 355 359 break; 356 360 } 361 362 newProg->program->bind(); 363 364 if (newProg->maskFragShader != QGLEngineSharedShaders::NoMaskFragmentShader) { 365 GLuint location = newProg->program->uniformLocation("maskTexture"); 366 newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT); 367 } 368 357 369 if (cachedPrograms.count() > 30) { 358 370 // The cache is full, so delete the last 5 programs in the list. … … 404 416 : ctx(context), 405 417 shaderProgNeedsChanging(true), 418 complexGeometry(false), 406 419 srcPixelType(Qt::NoBrush), 407 420 opacityMode(NoOpacity), … … 445 458 "invertedTextureSize", 446 459 "brushTransform", 447 "brushTexture" 460 "brushTexture", 461 "matrix" 448 462 }; 449 463 … … 753 767 requiredProgram.useTextureCoords = texCoords; 754 768 requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); 755 requiredProgram.usePmvMatrix = true; 769 if (complexGeometry && srcPixelType == Qt::SolidPattern) { 770 requiredProgram.positionVertexShader = QGLEngineSharedShaders::ComplexGeometryPositionOnlyVertexShader; 771 requiredProgram.usePmvMatrixAttribute = false; 772 } else { 773 requiredProgram.usePmvMatrixAttribute = true; 774 775 // Force complexGeometry off, since we currently don't support that mode for 776 // non-solid brushes 777 complexGeometry = false; 778 } 756 779 757 780 // At this point, requiredProgram is fully populated so try to find the program in the cache 758 781 currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); 759 782 760 if (currentShaderProg) { 761 currentShaderProg->program->bind(); 762 if (useCustomSrc) 763 customSrcStage->setUniforms(currentShaderProg->program); 783 if (currentShaderProg && useCustomSrc) { 784 customSrcStage->setUniforms(currentShaderProg->program); 764 785 } 765 786 -
trunk/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
r651 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) … … 73 73 calculations which logically belong in the fragment shader have been moved 74 74 into the vertex shader to improve performance. This is why the position 75 calculation is in a sep erate shader. Not only does it calculate the75 calculation is in a separate shader. Not only does it calculate the 76 76 position, but it also calculates some data to be passed to the fragment 77 77 shader as a varying. It is optimal to move as much of the calculation as … … 273 273 UntransformedPositionVertexShader, 274 274 PositionOnlyVertexShader, 275 ComplexGeometryPositionOnlyVertexShader, 275 276 PositionWithPatternBrushVertexShader, 276 277 PositionWithLinearGradientBrushVertexShader, … … 401 402 bool useTextureCoords; 402 403 bool useOpacityAttribute; 403 bool usePmvMatrix ;404 bool usePmvMatrixAttribute; 404 405 405 406 bool operator==(const QGLEngineShaderProg& other) { … … 447 448 BrushTransform, 448 449 BrushTexture, 450 Matrix, 449 451 NumUniforms 450 452 }; … … 456 458 }; 457 459 458 // There are optimi sations we can do, depending on the brush transform:460 // There are optimizations we can do, depending on the brush transform: 459 461 // 1) May not have to apply perspective-correction 460 462 // 2) Can use lower precision for matrix … … 475 477 void useSimpleProgram(); 476 478 void useBlitProgram(); 479 void setHasComplexGeometry(bool hasComplexGeometry) 480 { 481 complexGeometry = hasComplexGeometry; 482 shaderProgNeedsChanging = true; 483 } 484 bool hasComplexGeometry() const 485 { 486 return complexGeometry; 487 } 477 488 478 489 QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen … … 488 499 QGLContext* ctx; 489 500 bool shaderProgNeedsChanging; 501 bool complexGeometry; 490 502 491 503 // Current state variables which influence the choice of shader: -
trunk/src/opengl/gl2paintengineex/qglengineshadersource_p.h
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) … … 107 107 gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ 108 108 }\n"; 109 110 static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\ 111 uniform highp mat3 matrix; \n\ 112 attribute highp vec2 vertexCoordsArray; \n\ 113 void setPosition(void) \n\ 114 { \n\ 115 gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\ 116 } \n"; 109 117 110 118 static const char* const qglslUntransformedPositionVertexShader = "\n\ … … 275 283 uniform highp vec2 invertedTextureSize; \n\ 276 284 uniform highp mat3 brushTransform; \n\ 277 varying highp vec2 textureCoords; \n\285 varying highp vec2 brushTextureCoords; \n\ 278 286 void setPosition(void) \n\ 279 287 { \n\ … … 285 293 mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ 286 294 gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ 287 textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\295 brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ 288 296 }\n"; 289 297 … … 296 304 // TODO: Special case POT textures which don't need this emulation 297 305 static const char* const qglslTextureBrushSrcFragmentShader = "\n\ 298 varying highp vec2 textureCoords; \n\306 varying highp vec2 brushTextureCoords; \n\ 299 307 uniform lowp sampler2D brushTexture; \n\ 300 308 lowp vec4 srcPixel() { \n\ 301 return texture2D(brushTexture, fract( textureCoords)); \n\309 return texture2D(brushTexture, fract(brushTextureCoords)); \n\ 302 310 }\n"; 303 311 #else 304 312 static const char* const qglslTextureBrushSrcFragmentShader = "\n\ 305 varying highp vec2 textureCoords; \n\313 varying highp vec2 brushTextureCoords; \n\ 306 314 uniform lowp sampler2D brushTexture; \n\ 307 315 lowp vec4 srcPixel() \n\ 308 316 { \n\ 309 return texture2D(brushTexture, textureCoords); \n\317 return texture2D(brushTexture, brushTextureCoords); \n\ 310 318 }\n"; 311 319 #endif 312 320 313 321 static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ 314 varying highp vec2 textureCoords; \n\322 varying highp vec2 brushTextureCoords; \n\ 315 323 uniform lowp vec4 patternColor; \n\ 316 324 uniform lowp sampler2D brushTexture; \n\ 317 325 lowp vec4 srcPixel() \n\ 318 326 { \n\ 319 return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\327 return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\ 320 328 }\n"; 321 329 … … 333 341 lowp vec4 srcPixel() \n\ 334 342 { \n" 335 #ifdef QT_OPENGL_ES_2336 // work-around for driver bug337 "return 1.0 * texture2D(imageTexture, textureCoords); \n"338 #else339 343 "return texture2D(imageTexture, textureCoords); \n" 340 #endif341 344 "}\n"; 342 345 -
trunk/src/opengl/gl2paintengineex/qglgradientcache.cpp
r651 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) … … 40 40 ****************************************************************************/ 41 41 42 #include "qglgradientcache_p.h" 42 43 #include <private/qdrawhelper_p.h> 43 44 #include <private/qgl_p.h> 44 45 45 #include "qglgradientcache_p.h"46 46 47 47 QT_BEGIN_NAMESPACE -
trunk/src/opengl/gl2paintengineex/qglgradientcache_p.h
r651 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) -
trunk/src/opengl/gl2paintengineex/qpaintengineex_opengl2.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) … … 65 65 // #define QT_OPENGL_CACHE_AS_VBOS 66 66 67 #include "qglgradientcache_p.h" 67 68 #include "qpaintengineex_opengl2_p.h" 68 69 … … 78 79 #include <private/qpixmapdata_gl_p.h> 79 80 #include <private/qdatabuffer_p.h> 80 81 #include "qglgradientcache_p.h" 81 #include <private/qstatictext_p.h> 82 #include <private/qtriangulator_p.h> 83 82 84 #include "qglengineshadermanager_p.h" 83 85 #include "qgl2pexvertexarray_p.h" … … 89 91 QT_BEGIN_NAMESPACE 90 92 91 //#define QT_GL_NO_SCISSOR_TEST 93 #if defined(Q_OS_SYMBIAN) 94 #define QT_GL_NO_SCISSOR_TEST 95 #endif 96 92 97 #if defined(Q_WS_WIN) 93 98 extern Q_GUI_EXPORT bool qt_cleartype_enabled; 94 99 #endif 95 100 96 extern QImage qt_imageForBrush(int brushStyle, bool invert); 101 #ifdef Q_WS_MAC 102 extern bool qt_applefontsmoothing_enabled; 103 #endif 104 105 Q_DECL_IMPORT extern QImage qt_imageForBrush(int brushStyle, bool invert); 97 106 98 107 ////////////////////////////////// Private Methods ////////////////////////////////////////// … … 107 116 e->data = 0; 108 117 e->engine = 0; 118 } 119 120 if (elementIndicesVBOId != 0) { 121 glDeleteBuffers(1, &elementIndicesVBOId); 122 elementIndicesVBOId = 0; 109 123 } 110 124 } … … 150 164 151 165 currentBrush = brush; 166 if (!currentBrushPixmap.isNull()) 167 currentBrushPixmap = QPixmap(); 152 168 brushUniformsDirty = true; // All brushes have at least one uniform 153 169 … … 208 224 } 209 225 else if (style == Qt::TexturePattern) { 210 const QPixmap& texPixmap = currentBrush.texture(); 226 currentBrushPixmap = currentBrush.texture(); 227 228 int max_texture_size = ctx->d_func()->maxTextureSize(); 229 if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) 230 currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); 211 231 212 232 glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); 213 QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); 233 QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, 234 QGLContext::InternalBindOption | 235 QGLContext::CanFlipNativePixmapBindOption); 214 236 updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); 215 237 textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1; … … 366 388 dy = ceilf(dy - 0.5f); 367 389 } 368 390 #ifndef Q_OS_SYMBIAN 369 391 if (addOffset) { 370 392 dx += 0.49f; 371 393 dy += 0.49f; 372 394 } 373 395 #endif 374 396 pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13(); 375 397 pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23(); … … 389 411 390 412 matrixDirty = false; 413 matrixUniformDirty = true; 391 414 392 415 // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only … … 507 530 d->transferMode(BrushDrawingMode); 508 531 532 d->nativePaintingActive = true; 533 509 534 QGLContext *ctx = d->ctx; 510 535 glUseProgram(0); … … 522 547 float mv_matrix[4][4] = 523 548 { 524 { mtx.m11(), mtx.m12(), 0, mtx.m13() },525 { mtx.m21(), mtx.m22(), 0, mtx.m23() },526 { 0, 0, 1,0 },527 { mtx.dx(), mtx.dy(), 0, mtx.m33() }549 { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, 550 { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, 551 { 0, 0, 1, 0 }, 552 { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } 528 553 }; 529 554 … … 562 587 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 563 588 glStencilFunc(GL_ALWAYS, 0, 0xff); 564 glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);565 glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);566 glDisableVertexAttribArray(QT_OPACITY_ATTR);589 ctx->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); 590 ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); 591 ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); 567 592 #ifndef QT_OPENGL_ES_2 568 593 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // color may have been changed by glVertexAttrib() … … 574 599 Q_D(QGL2PaintEngineEx); 575 600 d->needsSync = true; 601 d->nativePaintingActive = false; 602 } 603 604 void QGL2PaintEngineEx::invalidateState() 605 { 606 Q_D(QGL2PaintEngineEx); 607 d->needsSync = true; 608 } 609 610 bool QGL2PaintEngineEx::isNativePaintingActive() const { 611 Q_D(const QGL2PaintEngineEx); 612 return d->nativePaintingActive; 576 613 } 577 614 … … 586 623 587 624 if (newMode == TextDrawingMode) { 588 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data()); 589 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data()); 625 shaderManager->setHasComplexGeometry(true); 626 } else { 627 shaderManager->setHasComplexGeometry(false); 590 628 } 591 629 … … 612 650 #ifdef QT_OPENGL_CACHE_AS_VBOS 613 651 GLuint vbo; 652 GLuint ibo; 614 653 #else 615 654 float *vertices; 655 void *indices; 616 656 #endif 617 657 int vertexCount; 658 int indexCount; 618 659 GLenum primitiveType; 619 660 qreal iscale; … … 626 667 Q_ASSERT(engine->type() == QPaintEngine::OpenGL2); 627 668 static_cast<QGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo; 669 if (c->ibo) 670 d->unusedIBOSToClean << c->ibo; 628 671 #else 629 672 Q_UNUSED(engine); 630 673 qFree(c->vertices); 674 qFree(c->indices); 631 675 #endif 632 676 delete c; … … 669 713 QVectorPath::CacheEntry *data = path.lookupCacheData(q); 670 714 QGL2PEVectorPathCache *cache; 715 716 bool updateCache = false; 671 717 672 718 if (data) { … … 679 725 glDeleteBuffers(1, &cache->vbo); 680 726 cache->vbo = 0; 727 Q_ASSERT(cache->ibo == 0); 681 728 #else 682 729 qFree(cache->vertices); 683 #endif 684 cache->vertexCount = 0; 730 Q_ASSERT(cache->indices == 0); 731 #endif 732 updateCache = true; 685 733 } 686 734 } 687 735 } else { 688 736 cache = new QGL2PEVectorPathCache; 689 cache->vertexCount = 0;690 737 data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath); 738 updateCache = true; 691 739 } 692 740 693 741 // Flatten the path at the current scale factor and fill it into the cache struct. 694 if ( !cache->vertexCount) {742 if (updateCache) { 695 743 vertexCoordinateArray.clear(); 696 744 vertexCoordinateArray.addPath(path, inverseScale, false); … … 698 746 int floatSizeInBytes = vertexCount * 2 * sizeof(float); 699 747 cache->vertexCount = vertexCount; 748 cache->indexCount = 0; 700 749 cache->primitiveType = GL_TRIANGLE_FAN; 701 750 cache->iscale = inverseScale; … … 704 753 glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); 705 754 glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); 755 cache->ibo = 0; 706 756 #else 707 757 cache->vertices = (float *) qMalloc(floatSizeInBytes); 708 758 memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); 759 cache->indices = 0; 709 760 #endif 710 761 } … … 722 773 // printf(" - Marking path as cachable...\n"); 723 774 // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable 724 // ### Remove before release... 725 static bool do_vectorpath_cache = qgetenv("QT_OPENGL_NO_PATH_CACHE").isEmpty(); 726 if (do_vectorpath_cache) 727 path.makeCacheable(); 775 path.makeCacheable(); 728 776 vertexCoordinateArray.clear(); 729 777 vertexCoordinateArray.addPath(path, inverseScale, false); … … 733 781 734 782 } else { 735 // The path is too complicated & needs the stencil technique 736 vertexCoordinateArray.clear(); 737 vertexCoordinateArray.addPath(path, inverseScale, false); 738 739 fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); 740 741 glStencilMask(0xff); 742 glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); 743 744 if (q->state()->clipTestEnabled) { 745 // Pass when high bit is set, replace stencil value with current clip 746 glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT); 747 } else if (path.hasWindingFill()) { 748 // Pass when any bit is set, replace stencil value with 0 749 glStencilFunc(GL_NOTEQUAL, 0, 0xff); 783 bool useCache = path.isCacheable(); 784 if (useCache) { 785 QRectF bbox = path.controlPointRect(); 786 // If the path doesn't fit within these limits, it is possible that the triangulation will fail. 787 useCache &= (bbox.left() > -0x8000 * inverseScale) 788 && (bbox.right() < 0x8000 * inverseScale) 789 && (bbox.top() > -0x8000 * inverseScale) 790 && (bbox.bottom() < 0x8000 * inverseScale); 791 } 792 793 if (useCache) { 794 QVectorPath::CacheEntry *data = path.lookupCacheData(q); 795 QGL2PEVectorPathCache *cache; 796 797 bool updateCache = false; 798 799 if (data) { 800 cache = (QGL2PEVectorPathCache *) data->data; 801 // Check if scale factor is exceeded for curved paths and generate curves if so... 802 if (path.isCurved()) { 803 qreal scaleFactor = cache->iscale / inverseScale; 804 if (scaleFactor < 0.5 || scaleFactor > 2.0) { 805 #ifdef QT_OPENGL_CACHE_AS_VBOS 806 glDeleteBuffers(1, &cache->vbo); 807 glDeleteBuffers(1, &cache->ibo); 808 #else 809 qFree(cache->vertices); 810 qFree(cache->indices); 811 #endif 812 updateCache = true; 813 } 814 } 815 } else { 816 cache = new QGL2PEVectorPathCache; 817 data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath); 818 updateCache = true; 819 } 820 821 // Flatten the path at the current scale factor and fill it into the cache struct. 822 if (updateCache) { 823 QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale)); 824 cache->vertexCount = polys.vertices.size() / 2; 825 cache->indexCount = polys.indices.size(); 826 cache->primitiveType = GL_TRIANGLES; 827 cache->iscale = inverseScale; 828 #ifdef QT_OPENGL_CACHE_AS_VBOS 829 glGenBuffers(1, &cache->vbo); 830 glGenBuffers(1, &cache->ibo); 831 glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); 832 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); 833 834 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) 835 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW); 836 else 837 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW); 838 839 QVarLengthArray<float> vertices(polys.vertices.size()); 840 for (int i = 0; i < polys.vertices.size(); ++i) 841 vertices[i] = float(inverseScale * polys.vertices.at(i)); 842 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW); 843 #else 844 cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size()); 845 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) { 846 cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size()); 847 memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size()); 848 } else { 849 cache->indices = (quint16 *) qMalloc(sizeof(quint16) * polys.indices.size()); 850 memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size()); 851 } 852 for (int i = 0; i < polys.vertices.size(); ++i) 853 cache->vertices[i] = float(inverseScale * polys.vertices.at(i)); 854 #endif 855 } 856 857 prepareForDraw(currentBrush.isOpaque()); 858 #ifdef QT_OPENGL_CACHE_AS_VBOS 859 glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); 860 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); 861 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); 862 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) 863 glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0); 864 else 865 glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0); 866 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 867 glBindBuffer(GL_ARRAY_BUFFER, 0); 868 #else 869 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); 870 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) 871 glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices); 872 else 873 glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices); 874 #endif 875 750 876 } else { 751 // Pass when high bit is set, replace stencil value with 0 752 glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); 753 } 754 prepareForDraw(currentBrush.isOpaque()); 755 756 // Stencil the brush onto the dest buffer 757 composite(vertexCoordinateArray.boundingRect()); 758 glStencilMask(0); 759 updateClipScissorTest(); 877 // printf(" - Marking path as cachable...\n"); 878 // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable 879 path.makeCacheable(); 880 881 // The path is too complicated & needs the stencil technique 882 vertexCoordinateArray.clear(); 883 vertexCoordinateArray.addPath(path, inverseScale, false); 884 885 fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); 886 887 glStencilMask(0xff); 888 glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); 889 890 if (q->state()->clipTestEnabled) { 891 // Pass when high bit is set, replace stencil value with current clip 892 glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT); 893 } else if (path.hasWindingFill()) { 894 // Pass when any bit is set, replace stencil value with 0 895 glStencilFunc(GL_NOTEQUAL, 0, 0xff); 896 } else { 897 // Pass when high bit is set, replace stencil value with 0 898 glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); 899 } 900 prepareForDraw(currentBrush.isOpaque()); 901 902 // Stencil the brush onto the dest buffer 903 composite(vertexCoordinateArray.boundingRect()); 904 glStencilMask(0); 905 updateClipScissorTest(); 906 } 760 907 } 761 908 } … … 939 1086 brushUniformsDirty = true; 940 1087 opacityUniformDirty = true; 1088 matrixUniformDirty = true; 941 1089 } 942 1090 … … 947 1095 shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); 948 1096 opacityUniformDirty = false; 1097 } 1098 1099 if (matrixUniformDirty && shaderManager->hasComplexGeometry()) { 1100 shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Matrix), 1101 pmvMatrix); 1102 matrixUniformDirty = false; 949 1103 } 950 1104 … … 1001 1155 } 1002 1156 1003 extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp1157 extern Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp 1004 1158 1005 1159 … … 1049 1203 updateMatrix(); 1050 1204 1205 QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled 1206 ? q->state()->rectangleClip 1207 : QRectF(0, 0, width, height)); 1208 1051 1209 if (penStyle == Qt::SolidLine) { 1052 stroker.process(path, pen );1210 stroker.process(path, pen, clip); 1053 1211 1054 1212 } else { // Some sort of dash 1055 dasher.process(path, pen );1213 dasher.process(path, pen, clip); 1056 1214 1057 1215 QVectorPath dashStroke(dasher.points(), 1058 1216 dasher.elementCount(), 1059 1217 dasher.elementTypes()); 1060 stroker.process(dashStroke, pen); 1061 } 1218 stroker.process(dashStroke, pen, clip); 1219 } 1220 1221 if (!stroker.vertexCount()) 1222 return; 1062 1223 1063 1224 if (opaque) { … … 1151 1312 1152 1313 1314 static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy) 1315 { 1316 return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy); 1317 } 1318 1153 1319 void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) 1154 1320 { 1155 1321 Q_D(QGL2PaintEngineEx); 1322 QGLContext *ctx = d->ctx; 1323 1324 int max_texture_size = ctx->d_func()->maxTextureSize(); 1325 if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { 1326 QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); 1327 1328 const qreal sx = scaled.width() / qreal(pixmap.width()); 1329 const qreal sy = scaled.height() / qreal(pixmap.height()); 1330 1331 drawPixmap(dest, scaled, scaleRect(src, sx, sy)); 1332 return; 1333 } 1334 1156 1335 ensureActive(); 1157 1336 d->transferMode(ImageDrawingMode); 1158 1337 1159 QGLContext *ctx = d->ctx;1160 1338 glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); 1161 1339 QGLTexture *texture = … … 1169 1347 1170 1348 bool isBitmap = pixmap.isQBitmap(); 1171 bool isOpaque = !isBitmap && !pixmap.hasAlpha Channel();1349 bool isOpaque = !isBitmap && !pixmap.hasAlpha(); 1172 1350 1173 1351 d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, … … 1180 1358 { 1181 1359 Q_D(QGL2PaintEngineEx); 1360 QGLContext *ctx = d->ctx; 1361 1362 int max_texture_size = ctx->d_func()->maxTextureSize(); 1363 if (image.width() > max_texture_size || image.height() > max_texture_size) { 1364 QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); 1365 1366 const qreal sx = scaled.width() / qreal(image.width()); 1367 const qreal sy = scaled.height() / qreal(image.height()); 1368 1369 drawImage(dest, scaled, scaleRect(src, sx, sy)); 1370 return; 1371 } 1372 1182 1373 ensureActive(); 1183 1374 d->transferMode(ImageDrawingMode); 1184 1375 1185 QGLContext *ctx = d->ctx;1186 1376 glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); 1377 1187 1378 QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); 1188 1379 GLuint id = texture->id; … … 1193 1384 } 1194 1385 1195 void QGL2PaintEngineEx::draw Texture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)1386 void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) 1196 1387 { 1197 1388 Q_D(QGL2PaintEngineEx); 1389 1390 ensureActive(); 1391 1392 QFontEngineGlyphCache::Type glyphType = textItem->fontEngine()->glyphFormat >= 0 1393 ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat) 1394 : d->glyphCacheType; 1395 if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { 1396 if (d->device->alphaRequested() || state()->matrix.type() > QTransform::TxTranslate 1397 || (state()->composition_mode != QPainter::CompositionMode_Source 1398 && state()->composition_mode != QPainter::CompositionMode_SourceOver)) 1399 { 1400 glyphType = QFontEngineGlyphCache::Raster_A8; 1401 } 1402 } 1403 1404 d->drawCachedGlyphs(glyphType, textItem); 1405 } 1406 1407 bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) 1408 { 1409 Q_D(QGL2PaintEngineEx); 1410 if (!d->shaderManager) 1411 return false; 1412 1198 1413 ensureActive(); 1199 1414 d->transferMode(ImageDrawingMode); … … 1210 1425 state()->renderHints & QPainter::SmoothPixmapTransform, textureId); 1211 1426 d->drawTexture(dest, srcRect, size, false); 1427 return true; 1212 1428 } 1213 1429 … … 1246 1462 1247 1463 if (drawCached) { 1248 d->drawCachedGlyphs(p, glyphType, ti); 1464 QVarLengthArray<QFixedPoint> positions; 1465 QVarLengthArray<glyph_t> glyphs; 1466 QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); 1467 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 1468 1469 { 1470 QStaticTextItem staticTextItem; 1471 staticTextItem.chars = const_cast<QChar *>(ti.chars); 1472 staticTextItem.setFontEngine(ti.fontEngine); 1473 staticTextItem.glyphs = glyphs.data(); 1474 staticTextItem.numChars = ti.num_chars; 1475 staticTextItem.numGlyphs = glyphs.size(); 1476 staticTextItem.glyphPositions = positions.data(); 1477 1478 d->drawCachedGlyphs(glyphType, &staticTextItem); 1479 } 1249 1480 return; 1250 1481 } … … 1253 1484 } 1254 1485 1255 void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, 1256 const QTextItemInt &ti) 1486 namespace { 1487 1488 class QOpenGLStaticTextUserData: public QStaticTextUserData 1489 { 1490 public: 1491 QOpenGLStaticTextUserData() 1492 : QStaticTextUserData(OpenGLUserData), cacheSize(0, 0) 1493 { 1494 } 1495 1496 ~QOpenGLStaticTextUserData() 1497 { 1498 } 1499 1500 QSize cacheSize; 1501 QGL2PEXVertexArray vertexCoordinateArray; 1502 QGL2PEXVertexArray textureCoordinateArray; 1503 QFontEngineGlyphCache::Type glyphType; 1504 }; 1505 1506 } 1507 1508 // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO 1509 1510 void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, 1511 QStaticTextItem *staticTextItem) 1257 1512 { 1258 1513 Q_Q(QGL2PaintEngineEx); 1259 1514 1260 QVarLengthArray<QFixedPoint> positions; 1261 QVarLengthArray<glyph_t> glyphs; 1262 QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); 1263 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 1515 QOpenGL2PaintEngineState *s = q->state(); 1516 1517 bool recreateVertexArrays = false; 1264 1518 1265 1519 QGLTextureGlyphCache *cache = 1266 (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, glyphType, QTransform()); 1267 1520 (QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(ctx, glyphType, QTransform()); 1268 1521 if (!cache || cache->cacheType() != glyphType) { 1269 1522 cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); 1270 ti.fontEngine->setGlyphCache(ctx, cache); 1271 } 1272 1273 cache->setPaintEnginePrivate(this); 1274 cache->populate(ti, glyphs, positions); 1523 staticTextItem->fontEngine()->setGlyphCache(ctx, cache); 1524 recreateVertexArrays = true; 1525 } else if (cache->context() == 0) { // Old context has been destroyed, new context has same ptr value 1526 cache->setContext(ctx); 1527 } 1528 1529 if (staticTextItem->userDataNeedsUpdate) { 1530 recreateVertexArrays = true; 1531 } else if (staticTextItem->userData() == 0) { 1532 recreateVertexArrays = true; 1533 } else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) { 1534 recreateVertexArrays = true; 1535 } else { 1536 QOpenGLStaticTextUserData *userData = static_cast<QOpenGLStaticTextUserData *>(staticTextItem->userData()); 1537 if (userData->glyphType != glyphType) 1538 recreateVertexArrays = true; 1539 } 1540 1541 // We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays. 1542 // If the cache size has changed, we do need to regenerate the vertices, but we don't need to repopulate the 1543 // cache so this text is performed before we test if the cache size has changed. 1544 if (recreateVertexArrays) { 1545 cache->setPaintEnginePrivate(this); 1546 if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, 1547 staticTextItem->glyphs, staticTextItem->glyphPositions)) { 1548 // No space in cache. We need to clear the cache and try again 1549 cache->clear(); 1550 cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, 1551 staticTextItem->glyphs, staticTextItem->glyphPositions); 1552 } 1553 } 1275 1554 1276 1555 if (cache->width() == 0 || cache->height() == 0) … … 1284 1563 GLfloat dy = 1.0 / cache->height(); 1285 1564 1286 vertexCoordinateArray.clear(); 1287 textureCoordinateArray.clear(); 1288 1289 for (int i=0; i<glyphs.size(); ++i) { 1290 const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]); 1291 int x = positions[i].x.toInt() + c.baseLineX - margin; 1292 int y = positions[i].y.toInt() - c.baseLineY - margin; 1293 1294 vertexCoordinateArray.addRect(QRectF(x, y, c.w, c.h)); 1295 textureCoordinateArray.addRect(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); 1296 } 1297 1298 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data()); 1299 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data()); 1565 // Use global arrays by default 1566 QGL2PEXVertexArray *vertexCoordinates = &vertexCoordinateArray; 1567 QGL2PEXVertexArray *textureCoordinates = &textureCoordinateArray; 1568 1569 if (staticTextItem->useBackendOptimizations) { 1570 QOpenGLStaticTextUserData *userData = 0; 1571 1572 if (staticTextItem->userData() == 0 1573 || staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) { 1574 1575 userData = new QOpenGLStaticTextUserData(); 1576 staticTextItem->setUserData(userData); 1577 1578 } else { 1579 userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData()); 1580 } 1581 1582 userData->glyphType = glyphType; 1583 1584 // Use cache if backend optimizations is turned on 1585 vertexCoordinates = &userData->vertexCoordinateArray; 1586 textureCoordinates = &userData->textureCoordinateArray; 1587 1588 QSize size(cache->width(), cache->height()); 1589 if (userData->cacheSize != size) { 1590 recreateVertexArrays = true; 1591 userData->cacheSize = size; 1592 } 1593 } 1594 1595 1596 if (recreateVertexArrays) { 1597 vertexCoordinates->clear(); 1598 textureCoordinates->clear(); 1599 1600 for (int i=0; i<staticTextItem->numGlyphs; ++i) { 1601 const QTextureGlyphCache::Coord &c = cache->coords.value(staticTextItem->glyphs[i]); 1602 int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin; 1603 int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin; 1604 1605 vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h)); 1606 textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); 1607 } 1608 1609 staticTextItem->userDataNeedsUpdate = false; 1610 } 1611 1612 if (elementIndices.size() < staticTextItem->numGlyphs*6) { 1613 Q_ASSERT(elementIndices.size() % 6 == 0); 1614 int j = elementIndices.size() / 6 * 4; 1615 while (j < staticTextItem->numGlyphs*4) { 1616 elementIndices.append(j + 0); 1617 elementIndices.append(j + 0); 1618 elementIndices.append(j + 1); 1619 elementIndices.append(j + 2); 1620 elementIndices.append(j + 3); 1621 elementIndices.append(j + 3); 1622 1623 j += 4; 1624 } 1625 1626 #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) 1627 if (elementIndicesVBOId == 0) 1628 glGenBuffers(1, &elementIndicesVBOId); 1629 1630 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); 1631 glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort), 1632 elementIndices.constData(), GL_STATIC_DRAW); 1633 #endif 1634 } else { 1635 #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) 1636 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); 1637 #endif 1638 } 1639 1640 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); 1641 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); 1300 1642 1301 1643 if (addOffset) { … … 1363 1705 updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); 1364 1706 1365 shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); 1366 glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); 1707 #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) 1708 glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, 0); 1709 #else 1710 glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); 1711 #endif 1367 1712 1368 1713 shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMaskPass2); … … 1389 1734 //### TODO: Gamma correction 1390 1735 1391 glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); 1392 glBindTexture(GL_TEXTURE_2D, cache->texture()); 1393 updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); 1394 1395 shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); 1396 glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); 1397 } 1398 1399 void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) 1736 QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; 1737 if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { 1738 1739 glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); 1740 if (lastMaskTextureUsed != cache->texture()) { 1741 glBindTexture(GL_TEXTURE_2D, cache->texture()); 1742 lastMaskTextureUsed = cache->texture(); 1743 } 1744 1745 if (cache->filterMode() != filterMode) { 1746 if (filterMode == QGLTextureGlyphCache::Linear) { 1747 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1748 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1749 } else { 1750 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1751 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1752 } 1753 cache->setFilterMode(filterMode); 1754 } 1755 } 1756 1757 #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) 1758 glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, 0); 1759 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1760 #else 1761 glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); 1762 #endif 1763 } 1764 1765 void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, 1766 QPainter::PixmapFragmentHints hints) 1400 1767 { 1401 1768 Q_D(QGL2PaintEngineEx); 1402 1769 // Use fallback for extended composition modes. 1403 1770 if (state()->composition_mode > QPainter::CompositionMode_Plus) { 1404 QPaintEngineEx::drawPixmap s(drawingData, dataCount, pixmap, hints);1771 QPaintEngineEx::drawPixmapFragments(fragments, fragmentCount, pixmap, hints); 1405 1772 return; 1406 1773 } 1407 1774 1408 1775 ensureActive(); 1409 d->drawPixmaps(drawingData, dataCount, pixmap, hints); 1410 } 1411 1412 1413 void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) 1776 int max_texture_size = d->ctx->d_func()->maxTextureSize(); 1777 if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { 1778 QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); 1779 d->drawPixmapFragments(fragments, fragmentCount, scaled, hints); 1780 } else { 1781 d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); 1782 } 1783 } 1784 1785 1786 void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments, 1787 int fragmentCount, const QPixmap &pixmap, 1788 QPainter::PixmapFragmentHints hints) 1414 1789 { 1415 1790 GLfloat dx = 1.0f / pixmap.size().width(); … … 1432 1807 bool allOpaque = true; 1433 1808 1434 for (int i = 0; i < dataCount; ++i) {1809 for (int i = 0; i < fragmentCount; ++i) { 1435 1810 qreal s = 0; 1436 1811 qreal c = 1; 1437 if ( drawingData[i].rotation != 0) {1438 s = qFastSin( drawingData[i].rotation * Q_PI / 180);1439 c = qFastCos( drawingData[i].rotation * Q_PI / 180);1440 } 1441 1442 qreal right = 0.5 * drawingData[i].scaleX * drawingData[i].source.width();1443 qreal bottom = 0.5 * drawingData[i].scaleY * drawingData[i].source.height();1812 if (fragments[i].rotation != 0) { 1813 s = qFastSin(fragments[i].rotation * Q_PI / 180); 1814 c = qFastCos(fragments[i].rotation * Q_PI / 180); 1815 } 1816 1817 qreal right = 0.5 * fragments[i].scaleX * fragments[i].width; 1818 qreal bottom = 0.5 * fragments[i].scaleY * fragments[i].height; 1444 1819 QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); 1445 1820 QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); 1446 1821 1447 vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); 1448 vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y()); 1449 vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); 1450 vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); 1451 vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y()); 1452 vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); 1453 1454 QGLRect src(drawingData[i].source.left() * dx, drawingData[i].source.top() * dy, 1455 drawingData[i].source.right() * dx, drawingData[i].source.bottom() * dy); 1456 1457 textureCoordinateArray.lineToArray(src.right, src.bottom); 1458 textureCoordinateArray.lineToArray(src.right, src.top); 1459 textureCoordinateArray.lineToArray(src.left, src.top); 1460 textureCoordinateArray.lineToArray(src.left, src.top); 1461 textureCoordinateArray.lineToArray(src.left, src.bottom); 1462 textureCoordinateArray.lineToArray(src.right, src.bottom); 1463 1464 qreal opacity = drawingData[i].opacity * q->state()->opacity; 1822 vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); 1823 vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); 1824 vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); 1825 vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); 1826 vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); 1827 vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); 1828 1829 QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy, 1830 (fragments[i].sourceLeft + fragments[i].width) * dx, 1831 (fragments[i].sourceTop + fragments[i].height) * dy); 1832 1833 textureCoordinateArray.addVertex(src.right, src.bottom); 1834 textureCoordinateArray.addVertex(src.right, src.top); 1835 textureCoordinateArray.addVertex(src.left, src.top); 1836 textureCoordinateArray.addVertex(src.left, src.top); 1837 textureCoordinateArray.addVertex(src.left, src.bottom); 1838 textureCoordinateArray.addVertex(src.right, src.bottom); 1839 1840 qreal opacity = fragments[i].opacity * q->state()->opacity; 1465 1841 opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; 1466 1842 allOpaque &= (opacity >= 0.99f); … … 1475 1851 // Flip texture y-coordinate. 1476 1852 QGLPoint *data = textureCoordinateArray.data(); 1477 for (int i = 0; i < 6 * dataCount; ++i)1853 for (int i = 0; i < 6 * fragmentCount; ++i) 1478 1854 data[i].y = 1 - data[i].y; 1479 1855 } … … 1482 1858 1483 1859 bool isBitmap = pixmap.isQBitmap(); 1484 bool isOpaque = !isBitmap && (!pixmap.hasAlpha Channel() || (hints & QDrawPixmaps::OpaqueHint)) && allOpaque;1860 bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; 1485 1861 1486 1862 updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, … … 1489 1865 // Setup for texture drawing 1490 1866 currentBrush = noBrush; 1491 shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); 1867 shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc 1868 : QGLEngineShaderManager::ImageSrc); 1492 1869 if (prepareForDraw(isOpaque)) 1493 1870 shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); … … 1498 1875 } 1499 1876 1500 glDrawArrays(GL_TRIANGLES, 0, 6 * dataCount);1877 glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount); 1501 1878 } 1502 1879 … … 1523 1900 d->brushTextureDirty = true; 1524 1901 d->brushUniformsDirty = true; 1902 d->matrixUniformDirty = true; 1525 1903 d->matrixDirty = true; 1526 1904 d->compositionModeDirty = true; … … 1560 1938 #if defined(Q_WS_WIN) 1561 1939 if (qt_cleartype_enabled) 1940 #endif 1941 #if defined(Q_WS_MAC) 1942 if (qt_applefontsmoothing_enabled) 1562 1943 #endif 1563 1944 d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; … … 1605 1986 d->unusedVBOSToClean.clear(); 1606 1987 } 1988 if (!d->unusedIBOSToClean.isEmpty()) { 1989 glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData()); 1990 d->unusedIBOSToClean.clear(); 1991 } 1607 1992 #endif 1608 1993 … … 1626 2011 glViewport(0, 0, d->width, d->height); 1627 2012 d->needsSync = false; 2013 d->lastMaskTextureUsed = 0; 1628 2014 d->shaderManager->setDirty(); 1629 2015 d->ctx->d_func()->syncGlState(); … … 1806 2192 QRectF rect(points[0], points[2]); 1807 2193 1808 if (state()->matrix.type() <= QTransform::TxScale) { 2194 if (state()->matrix.type() <= QTransform::TxScale 2195 || (state()->matrix.type() == QTransform::TxRotate 2196 && qFuzzyIsNull(state()->matrix.m11()) 2197 && qFuzzyIsNull(state()->matrix.m22()))) 2198 { 1809 2199 state()->rectangleClip = state()->rectangleClip.intersected(state()->matrix.mapRect(rect).toRect()); 1810 2200 d->updateClipScissorTest(); -
trunk/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
r651 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) … … 124 124 virtual void transformChanged(); 125 125 126 virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);127 126 virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); 128 virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints); 127 virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, 128 QPainter::PixmapFragmentHints hints); 129 129 virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, 130 130 Qt::ImageConversionFlags flags = Qt::AutoColor); … … 134 134 virtual void clip(const QVectorPath &path, Qt::ClipOperation op); 135 135 136 virtual void drawStaticTextItem(QStaticTextItem *textItem); 137 138 bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); 136 139 137 140 Type type() const { return OpenGL2; } … … 149 152 void endNativePainting(); 150 153 154 void invalidateState(); 155 151 156 QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype); 152 157 153 158 void setRenderTextActive(bool); 154 159 160 bool isNativePaintingActive() const; 155 161 private: 156 162 Q_DISABLE_COPY(QGL2PaintEngineEx) 157 163 }; 158 159 164 160 165 class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate … … 174 179 ctx(0), 175 180 useSystemClip(true), 181 elementIndicesVBOId(0), 182 opacityArray(0), 176 183 snapToPixelGrid(false), 177 184 addOffset(false), 178 inverseScale(1) 185 nativePaintingActive(false), 186 inverseScale(1), 187 lastMaskTextureUsed(0) 179 188 { } 180 189 … … 194 203 void stroke(const QVectorPath &path, const QPen &pen); 195 204 void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); 196 void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints); 197 void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti); 205 void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, 206 QPainter::PixmapFragmentHints hints); 207 void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem); 198 208 199 209 // Calls glVertexAttributePointer if the pointer has changed … … 254 264 bool brushUniformsDirty; 255 265 bool opacityUniformDirty; 266 bool matrixUniformDirty; 256 267 257 268 bool stencilClean; // Has the stencil not been used for clipping so far? … … 264 275 const QBrush noBrush; 265 276 277 QPixmap currentBrushPixmap; 278 266 279 QGL2PEXVertexArray vertexCoordinateArray; 267 280 QGL2PEXVertexArray textureCoordinateArray; 281 QVector<GLushort> elementIndices; 282 GLuint elementIndicesVBOId; 268 283 QDataBuffer<GLfloat> opacityArray; 269 284 GLfloat staticVertexCoordinateArray[8]; … … 272 287 bool snapToPixelGrid; 273 288 bool addOffset; // When enabled, adds a 0.49,0.49 offset to matrix in updateMatrix 289 bool nativePaintingActive; 274 290 GLfloat pmvMatrix[3][3]; 275 291 GLfloat inverseScale; 276 292 277 293 GLuint lastTextureUsed; 294 GLuint lastMaskTextureUsed; 278 295 279 296 bool needsSync; … … 294 311 QSet<QVectorPath::CacheEntry *> pathCaches; 295 312 QVector<GLuint> unusedVBOSToClean; 313 QVector<GLuint> unusedIBOSToClean; 296 314 297 315 const GLfloat *vertexAttribPointers[3]; -
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 -
trunk/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
r651 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) … … 63 63 class QGL2PaintEngineExPrivate; 64 64 65 class Q GLTextureGlyphCache : public QObject, public QTextureGlyphCache65 class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache 66 66 { 67 67 Q_OBJECT … … 73 73 virtual void resizeTextureData(int width, int height); 74 74 virtual void fillTexture(const Coord &c, glyph_t glyph); 75 virtual int glyphMargin() const; 75 virtual int glyphPadding() const; 76 virtual int maxTextureWidth() const; 77 virtual int maxTextureHeight() const; 76 78 77 79 inline GLuint texture() const { return m_texture; } … … 82 84 inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; } 83 85 86 enum FilterMode { 87 Nearest, 88 Linear 89 }; 90 FilterMode filterMode() const { return m_filterMode; } 91 void setFilterMode(FilterMode m) { m_filterMode = m; } 92 93 void setContext(QGLContext *context); 94 QGLContext *context() const { return ctx; } 84 95 85 96 public Q_SLOTS: … … 91 102 // destroy the fbo and texture here, but since the context 92 103 // is about to be destroyed, the GL server will do the 93 // clean up for us anyway 104 // clean up for us anyway. We reset everything, so that the 105 // glyph cache object can be reused later by setting a new 106 // context on it. 94 107 m_fbo = 0; 95 108 m_texture = 0; 96 109 ctx = 0; 110 m_width = 0; 111 m_height = 0; 112 m_w = 0; 113 m_h = 0; 114 m_cx = 0; 115 m_cy = 0; 116 m_currentRowHeight = 0; 117 coords.clear(); 97 118 } else { 98 119 // since the context holding the texture is shared, and … … 103 124 } 104 125 } 126 127 void clear(); 105 128 106 129 private: … … 116 139 117 140 QGLShaderProgram *m_program; 141 142 FilterMode m_filterMode; 118 143 }; 119 144 -
trunk/src/opengl/gl2paintengineex/qtriangulatingstroker.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) … … 74 74 75 75 76 void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen )76 void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &) 77 77 { 78 78 const qreal *pts = path.points(); … … 112 112 // 113 113 // The curvyness value of PI/14 was based on, 114 // arcLength =2*PI*r/4=PI/2 and splitting length into somewhere114 // arcLength = 2*PI*r/4 = PI*r/2 and splitting length into somewhere 115 115 // between 3 and 8 where 5 seemed to be give pretty good results 116 116 // hence: Q_PI/14. Lower divisors will give more detail at the … … 482 482 483 483 QDashedStrokeProcessor::QDashedStrokeProcessor() 484 : m_dash_stroker(0), m_inv_scale(1) 484 : m_points(0), m_types(0), 485 m_dash_stroker(0), m_inv_scale(1) 485 486 { 486 487 m_dash_stroker.setMoveToHook(qdashprocessor_moveTo); … … 489 490 } 490 491 491 void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen )492 void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip) 492 493 { 493 494 … … 496 497 int count = path.elementCount(); 497 498 499 bool cosmetic = pen.isCosmetic(); 500 498 501 m_points.reset(); 499 502 m_types.reset(); 503 m_points.reserve(path.elementCount()); 504 m_types.reserve(path.elementCount()); 500 505 501 506 qreal width = qpen_widthf(pen); … … 504 509 505 510 m_dash_stroker.setDashPattern(pen.dashPattern()); 506 m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width); 511 m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width); 512 m_dash_stroker.setDashOffset(pen.dashOffset()); 507 513 m_dash_stroker.setMiterLimit(pen.miterLimit()); 508 qreal curvyness = sqrt(width) * m_inv_scale / 8; 514 m_dash_stroker.setClipRect(clip); 515 516 float curvynessAdd, curvynessMul, roundness = 0; 517 518 // simplfy pens that are thin in device size (2px wide or less) 519 if (width < 2.5 && (cosmetic || m_inv_scale == 1)) { 520 curvynessAdd = 0.5; 521 curvynessMul = CURVE_FLATNESS / m_inv_scale; 522 roundness = 1; 523 } else if (cosmetic) { 524 curvynessAdd= width / 2; 525 curvynessMul= CURVE_FLATNESS; 526 roundness = qMax<int>(4, width * CURVE_FLATNESS); 527 } else { 528 curvynessAdd = width * m_inv_scale; 529 curvynessMul = CURVE_FLATNESS / m_inv_scale; 530 roundness = qMax<int>(4, width * curvynessMul); 531 } 509 532 510 533 if (count < 2) … … 541 564 *(((const QPointF *) pts) + 2)); 542 565 QRectF bounds = b.bounds(); 543 int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * curvyness); 566 float rad = qMax(bounds.width(), bounds.height()); 567 int threshold = qMin<float>(64, (rad + curvynessAdd) * curvynessMul); 544 568 if (threshold < 4) 545 569 threshold = 4; 570 546 571 qreal threshold_minus_1 = threshold - 1; 547 572 for (int i=0; i<threshold; ++i) { -
trunk/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h
r651 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) … … 55 55 { 56 56 public: 57 void process(const QVectorPath &path, const QPen &pen); 57 QTriangulatingStroker() : m_vertices(0) {} 58 void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); 58 59 59 60 inline int vertexCount() const { return m_vertices.size(); } … … 97 98 QDashedStrokeProcessor(); 98 99 99 void process(const QVectorPath &path, const QPen &pen );100 void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); 100 101 101 102 inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) { -
trunk/src/opengl/opengl.pro
r651 r846 6 6 win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x63000000 7 7 solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2 8 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused 8 9 9 10 unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui … … 11 12 include(../qbase.pri) 12 13 13 !win32:!embedded:!mac: CONFIG += x1114 !win32:!embedded:!mac:!symbian:CONFIG += x11 14 15 contains(QT_CONFIG, opengl):CONFIG += opengl 15 16 contains(QT_CONFIG, opengles1):CONFIG += opengles1 16 contains(QT_CONFIG, opengles1cl):CONFIG += opengles1cl17 17 contains(QT_CONFIG, opengles2):CONFIG += opengles2 18 18 contains(QT_CONFIG, egl):CONFIG += egl 19 19 20 20 HEADERS += qgl.h \ 21 22 23 21 qgl_p.h \ 22 qglcolormap.h \ 23 qglpixelbuffer.h \ 24 24 qglpixelbuffer_p.h \ 25 25 qglframebufferobject.h \ 26 26 qglframebufferobject_p.h \ 27 27 qglextensions_p.h \ 28 28 qglpaintdevice_p.h \ 29 qglbuffer.h \ 29 30 30 31 31 32 SOURCES += qgl.cpp \ 32 33 34 33 qglcolormap.cpp \ 34 qglpixelbuffer.cpp \ 35 qglframebufferobject.cpp \ 35 36 qglextensions.cpp \ 36 37 qglpaintdevice.cpp \ 38 qglbuffer.cpp \ 37 39 38 40 … … 42 44 } 43 45 44 !contains(QT_CONFIG, opengles1) :!contains(QT_CONFIG, opengles1cl){46 !contains(QT_CONFIG, opengles1) { 45 47 HEADERS += qglshaderprogram.h \ 46 48 qglpixmapfilter_p.h \ … … 56 58 gl2paintengineex/qglcustomshaderstage_p.h \ 57 59 gl2paintengineex/qtriangulatingstroker_p.h \ 60 gl2paintengineex/qtriangulator_p.h \ 58 61 gl2paintengineex/qtextureglyphcache_gl_p.h 59 62 … … 70 73 gl2paintengineex/qglcustomshaderstage.cpp \ 71 74 gl2paintengineex/qtriangulatingstroker.cpp \ 75 gl2paintengineex/qtriangulator.cpp \ 72 76 gl2paintengineex/qtextureglyphcache_gl.cpp 73 77 … … 75 79 76 80 x11 { 77 contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles1cl)|contains(QT_CONFIG, opengles2) {81 contains(QT_CONFIG, egl) { 78 82 SOURCES += qgl_x11egl.cpp \ 79 83 qglpixelbuffer_egl.cpp \ … … 114 118 } 115 119 win32:!wince*: { 120 DEFINES += QT_NO_EGL 116 121 SOURCES += qgl_win.cpp \ 117 qglpixelbuffer_win.cpp122 qglpixelbuffer_win.cpp 118 123 } 119 124 wince*: { … … 122 127 qgl_egl.cpp 123 128 124 HEADERS += qgl_cl_p.h \ 125 qgl_egl_p.h \ 129 HEADERS += qgl_egl_p.h 126 130 } 127 131 … … 144 148 } 145 149 150 symbian { 151 SOURCES += qgl_symbian.cpp \ 152 qglpixelbuffer_egl.cpp \ 153 qgl_egl.cpp 154 155 HEADERS += qgl_egl_p.h 156 157 symbian:TARGET.UID3 = 0x2002131A 158 } 159 146 160 INCLUDEPATH += ../3rdparty/harfbuzz/src -
trunk/src/opengl/qgl.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) … … 50 50 #define INT32 dummy_INT32 51 51 #define INT8 dummy_INT8 52 #if !defined(QT_OPENGL_ES)52 #ifdef QT_NO_EGL 53 53 # include <GL/glx.h> 54 54 #endif … … 68 68 #include "qgl_p.h" 69 69 70 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)70 #if !defined(QT_OPENGL_ES_1) 71 71 #include "gl2paintengineex/qpaintengineex_opengl2_p.h" 72 72 #endif … … 92 92 #include "qfile.h" 93 93 #include "qlibrary.h" 94 #include <qmutex.h> 94 95 95 96 96 97 QT_BEGIN_NAMESPACE 97 98 98 #ifdef QT_OPENGL_ES_1_CL 99 #include "qgl_cl_p.h" 100 #endif 101 102 103 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) 99 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) 104 100 QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs; 105 101 #endif … … 132 128 QGLSignalProxy *QGLSignalProxy::instance() 133 129 { 134 return theSignalProxy(); 130 QGLSignalProxy *proxy = theSignalProxy(); 131 if (proxy && proxy->thread() != qApp->thread()) { 132 if (proxy->thread() == QThread::currentThread()) 133 proxy->moveToThread(qApp->thread()); 134 } 135 return proxy; 135 136 } 136 137 … … 227 228 \value HasOverlay Enables the use of an overlay. 228 229 \value SampleBuffers Enables the use of sample buffers. 230 \value DeprecatedFunctions Enables the use of deprecated functionality for OpenGL 3.x 231 contexts. A context with deprecated functionality enabled is 232 called a full context in the OpenGL specification. 229 233 \value SingleBuffer Specifies the use of a single buffer, as opposed to double buffers. 230 234 \value NoDepthBuffer Disables the use of a depth buffer. … … 237 241 \value NoOverlay Disables the use of an overlay. 238 242 \value NoSampleBuffers Disables the use of sample buffers. 243 \value NoDeprecatedFunctions Disables the use of deprecated functionality for OpenGL 3.x 244 contexts. A context with deprecated functionality disabled is 245 called a forward compatible context in the OpenGL specification. 239 246 240 247 \sa {Sample Buffers Example} … … 508 515 flicker-free drawing and often better performance. 509 516 517 Note that single buffered contexts are currently not supported 518 with EGL. 519 510 520 \sa doubleBuffer(), QGLContext::swapBuffers(), 511 521 QGLWidget::swapBuffers() … … 766 776 } 767 777 d->numSamples = numSamples; 778 setSampleBuffers(numSamples > 0); 768 779 } 769 780 … … 904 915 } 905 916 d->depthSize = size; 917 setDepth(size > 0); 906 918 } 907 919 … … 1017 1029 } 1018 1030 d->alphaSize = size; 1019 set Option(QGL::AlphaChannel);1031 setAlpha(size > 0); 1020 1032 } 1021 1033 … … 1044 1056 } 1045 1057 d->accumSize = size; 1058 setAccum(size > 0); 1046 1059 } 1047 1060 … … 1069 1082 } 1070 1083 d->stencilSize = size; 1084 setStencil(size > 0); 1071 1085 } 1072 1086 … … 1080 1094 return d->stencilSize; 1081 1095 } 1096 1097 /*! 1098 \since 4.7 1099 1100 Set the OpenGL version to the \a major and \a minor numbers. If a 1101 context compatible with the requested OpenGL version cannot be 1102 created, a context compatible with version 1.x is created instead. 1103 1104 \sa majorVersion(), minorVersion() 1105 */ 1106 void QGLFormat::setVersion(int major, int minor) 1107 { 1108 if (major < 1 || minor < 0) { 1109 qWarning("QGLFormat::setVersion: Cannot set zero or negative version number %d.%d", major, minor); 1110 return; 1111 } 1112 detach(); 1113 d->majorVersion = major; 1114 d->minorVersion = minor; 1115 } 1116 1117 /*! 1118 \since 4.7 1119 1120 Returns the OpenGL major version. 1121 1122 \sa setVersion(), minorVersion() 1123 */ 1124 int QGLFormat::majorVersion() const 1125 { 1126 return d->majorVersion; 1127 } 1128 1129 /*! 1130 \since 4.7 1131 1132 Returns the OpenGL minor version. 1133 1134 \sa setVersion(), majorVersion() 1135 */ 1136 int QGLFormat::minorVersion() const 1137 { 1138 return d->minorVersion; 1139 } 1140 1141 /*! 1142 \enum QGLFormat::OpenGLContextProfile 1143 \since 4.7 1144 1145 This enum describes the OpenGL context profiles that can be 1146 specified for contexts implementing OpenGL version 3.2 or 1147 higher. These profiles are different from OpenGL ES profiles. 1148 1149 \value NoProfile OpenGL version is lower than 3.2. 1150 \value CoreProfile Functionality deprecated in OpenGL version 3.0 is not available. 1151 \value CompatibilityProfile Functionality from earlier OpenGL versions is available. 1152 */ 1153 1154 /*! 1155 \since 4.7 1156 1157 Set the OpenGL context profile to \a profile. The \a profile is 1158 ignored if the requested OpenGL version is less than 3.2. 1159 1160 \sa profile() 1161 */ 1162 void QGLFormat::setProfile(OpenGLContextProfile profile) 1163 { 1164 detach(); 1165 d->profile = profile; 1166 } 1167 1168 /*! 1169 \since 4.7 1170 1171 Returns the OpenGL context profile. 1172 1173 \sa setProfile() 1174 */ 1175 QGLFormat::OpenGLContextProfile QGLFormat::profile() const 1176 { 1177 return d->profile; 1178 } 1179 1082 1180 1083 1181 /*! … … 1117 1215 versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 | 1118 1216 QGLFormat::OpenGL_ES_CommonLite_Version_1_1; 1119 } 1120 else { 1217 } else { 1121 1218 // Not -CM, must be CL, CommonLite 1122 1219 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0; … … 1124 1221 versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1; 1125 1222 } 1126 } 1127 else { 1223 } else { 1128 1224 // OpenGL ES version 2.0 or higher 1129 1225 versionFlags |= QGLFormat::OpenGL_ES_Version_2_0; 1130 1226 } 1131 } 1132 else { 1227 } else { 1133 1228 // if < 3 parts to the name, it is an unrecognised OpenGL ES 1134 1229 qWarning("Unrecognised OpenGL ES version"); 1135 1230 } 1136 } 1137 else { 1231 } else { 1138 1232 // not ES, regular OpenGL, the version numbers are first in the string 1139 1233 if (versionString.startsWith(QLatin1String("1."))) { … … 1152 1246 break; 1153 1247 } 1154 } 1155 else if (versionString.startsWith(QLatin1String("2."))) { 1248 } else if (versionString.startsWith(QLatin1String("2."))) { 1156 1249 versionFlags |= QGLFormat::OpenGL_Version_1_1 | 1157 1250 QGLFormat::OpenGL_Version_1_2 | … … 1160 1253 QGLFormat::OpenGL_Version_1_5 | 1161 1254 QGLFormat::OpenGL_Version_2_0; 1162 QString minorVersion = versionString.section(QLatin1Char(' '), 0, 0).section(QLatin1Char('.'), 1, 1); 1163 if (minorVersion == QChar(QLatin1Char('1'))) 1255 if (versionString[2].toAscii() == '1') 1164 1256 versionFlags |= QGLFormat::OpenGL_Version_2_1; 1257 } else if (versionString.startsWith(QLatin1String("3."))) { 1258 versionFlags |= QGLFormat::OpenGL_Version_1_1 | 1259 QGLFormat::OpenGL_Version_1_2 | 1260 QGLFormat::OpenGL_Version_1_3 | 1261 QGLFormat::OpenGL_Version_1_4 | 1262 QGLFormat::OpenGL_Version_1_5 | 1263 QGLFormat::OpenGL_Version_2_0 | 1264 QGLFormat::OpenGL_Version_2_1 | 1265 QGLFormat::OpenGL_Version_3_0; 1266 switch (versionString[2].toAscii()) { 1267 case '3': 1268 versionFlags |= QGLFormat::OpenGL_Version_3_3; 1269 case '2': 1270 versionFlags |= QGLFormat::OpenGL_Version_3_2; 1271 case '1': 1272 versionFlags |= QGLFormat::OpenGL_Version_3_1; 1273 case '0': 1274 break; 1275 default: 1276 versionFlags |= QGLFormat::OpenGL_Version_3_1 | 1277 QGLFormat::OpenGL_Version_3_2 | 1278 QGLFormat::OpenGL_Version_3_3; 1279 break; 1280 } 1281 } else if (versionString.startsWith(QLatin1String("4."))) { 1282 versionFlags |= QGLFormat::OpenGL_Version_1_1 | 1283 QGLFormat::OpenGL_Version_1_2 | 1284 QGLFormat::OpenGL_Version_1_3 | 1285 QGLFormat::OpenGL_Version_1_4 | 1286 QGLFormat::OpenGL_Version_1_5 | 1287 QGLFormat::OpenGL_Version_2_0 | 1288 QGLFormat::OpenGL_Version_2_1 | 1289 QGLFormat::OpenGL_Version_3_0 | 1290 QGLFormat::OpenGL_Version_3_1 | 1291 QGLFormat::OpenGL_Version_3_2 | 1292 QGLFormat::OpenGL_Version_3_3 | 1293 QGLFormat::OpenGL_Version_4_0; 1294 } else { 1295 versionFlags |= QGLFormat::OpenGL_Version_1_1 | 1296 QGLFormat::OpenGL_Version_1_2 | 1297 QGLFormat::OpenGL_Version_1_3 | 1298 QGLFormat::OpenGL_Version_1_4 | 1299 QGLFormat::OpenGL_Version_1_5 | 1300 QGLFormat::OpenGL_Version_2_0 | 1301 QGLFormat::OpenGL_Version_2_1 | 1302 QGLFormat::OpenGL_Version_3_0 | 1303 QGLFormat::OpenGL_Version_3_1 | 1304 QGLFormat::OpenGL_Version_3_2 | 1305 QGLFormat::OpenGL_Version_3_3 | 1306 QGLFormat::OpenGL_Version_4_0; 1165 1307 } 1166 else if (versionString.startsWith(QLatin1String("3."))) {1167 versionFlags |= QGLFormat::OpenGL_Version_1_1 |1168 QGLFormat::OpenGL_Version_1_2 |1169 QGLFormat::OpenGL_Version_1_3 |1170 QGLFormat::OpenGL_Version_1_4 |1171 QGLFormat::OpenGL_Version_1_5 |1172 QGLFormat::OpenGL_Version_2_0 |1173 QGLFormat::OpenGL_Version_2_1 |1174 QGLFormat::OpenGL_Version_3_0;1175 }1176 else1177 qWarning("Unrecognised OpenGL version");1178 1308 } 1179 1309 return versionFlags; … … 1206 1336 1207 1337 \value OpenGL_Version_3_0 OpenGL version 3.0 or higher is present. 1338 1339 \value OpenGL_Version_3_1 OpenGL version 3.1 or higher is present. 1340 Note that OpenGL version 3.1 or higher does not necessarily support all the features of 1341 version 3.0 and lower. 1342 1343 \value OpenGL_Version_3_2 OpenGL version 3.2 or higher is present. 1344 1345 \value OpenGL_Version_3_3 OpenGL version 3.3 or higher is present. 1346 1347 \value OpenGL_Version_4_0 OpenGL version 4.0 or higher is present. 1208 1348 1209 1349 \value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present. … … 1378 1518 bool operator==(const QGLFormat& a, const QGLFormat& b) 1379 1519 { 1380 return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize 1381 && a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize 1520 return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts 1521 && a.d->pln == b.d->pln 1522 && a.d->alphaSize == b.d->alphaSize 1523 && a.d->accumSize == b.d->accumSize 1524 && a.d->stencilSize == b.d->stencilSize 1382 1525 && a.d->depthSize == b.d->depthSize 1383 1526 && a.d->redSize == b.d->redSize … … 1385 1528 && a.d->blueSize == b.d->blueSize 1386 1529 && a.d->numSamples == b.d->numSamples 1387 && a.d->swapInterval == b.d->swapInterval; 1388 } 1530 && a.d->swapInterval == b.d->swapInterval 1531 && a.d->majorVersion == b.d->majorVersion 1532 && a.d->minorVersion == b.d->minorVersion 1533 && a.d->profile == b.d->profile); 1534 } 1535 1536 #ifndef QT_NO_DEBUG_STREAM 1537 QDebug operator<<(QDebug dbg, const QGLFormat &f) 1538 { 1539 const QGLFormatPrivate * const d = f.d; 1540 1541 dbg.nospace() << "QGLFormat(" 1542 << "options " << d->opts 1543 << ", plane " << d->pln 1544 << ", depthBufferSize " << d->depthSize 1545 << ", accumBufferSize " << d->accumSize 1546 << ", stencilBufferSize " << d->stencilSize 1547 << ", redBufferSize " << d->redSize 1548 << ", greenBufferSize " << d->greenSize 1549 << ", blueBufferSize " << d->blueSize 1550 << ", alphaBufferSize " << d->alphaSize 1551 << ", samples " << d->numSamples 1552 << ", swapInterval " << d->swapInterval 1553 << ", majorVersion " << d->majorVersion 1554 << ", minorVersion " << d->minorVersion 1555 << ", profile " << d->profile 1556 << ')'; 1557 1558 return dbg.space(); 1559 } 1560 #endif 1389 1561 1390 1562 … … 1400 1572 return !(a == b); 1401 1573 } 1574 1575 struct QGLContextGroupList { 1576 void append(QGLContextGroup *group) { 1577 QMutexLocker locker(&m_mutex); 1578 m_list.append(group); 1579 } 1580 1581 void remove(QGLContextGroup *group) { 1582 QMutexLocker locker(&m_mutex); 1583 m_list.removeOne(group); 1584 } 1585 1586 QList<QGLContextGroup *> m_list; 1587 QMutex m_mutex; 1588 }; 1589 1590 Q_GLOBAL_STATIC(QGLContextGroupList, qt_context_groups) 1402 1591 1403 1592 /***************************************************************************** 1404 1593 QGLContext implementation 1405 1594 *****************************************************************************/ 1595 1596 QGLContextGroup::QGLContextGroup(const QGLContext *context) 1597 : m_context(context), m_guards(0), m_refs(1) 1598 { 1599 qt_context_groups()->append(this); 1600 } 1406 1601 1407 1602 QGLContextGroup::~QGLContextGroup() … … 1414 1609 guard = guard->m_next; 1415 1610 } 1611 qt_context_groups()->remove(this); 1416 1612 } 1417 1613 … … 1447 1643 } 1448 1644 1645 QGLContextPrivate::QGLContextPrivate(QGLContext *context) 1646 : internal_context(false) 1647 , q_ptr(context) 1648 { 1649 group = new QGLContextGroup(context); 1650 texture_destroyer = new QGLTextureDestroyer; 1651 texture_destroyer->moveToThread(qApp->thread()); 1652 } 1653 1449 1654 QGLContextPrivate::~QGLContextPrivate() 1450 1655 { … … 1453 1658 delete group; 1454 1659 } 1660 1661 delete texture_destroyer; 1455 1662 } 1456 1663 … … 1481 1688 vi = 0; 1482 1689 #endif 1483 #if defined(QT_OPENGL_ES) 1690 #ifndef QT_NO_EGL 1691 ownsEglContext = false; 1484 1692 eglContext = 0; 1485 1693 eglSurface = EGL_NO_SURFACE; … … 1497 1705 default_fbo = 0; 1498 1706 active_engine = 0; 1707 workaround_needsFullClearOnEveryFrame = false; 1708 workaround_brokenFBOReadBack = false; 1709 workaround_brokenTexSubImage = false; 1710 workaroundsCached = false; 1711 1712 workaround_brokenTextureFromPixmap = false; 1713 workaround_brokenTextureFromPixmap_init = false; 1714 1499 1715 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) 1500 1716 vertexAttributeArraysEnabledState[i] = false; … … 1567 1783 int w = size.width(); 1568 1784 int h = size.height(); 1569 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)1785 #if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) 1570 1786 //### glGetTexImage not in GL ES 2.0, need to do something else here! 1571 1787 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); … … 1595 1811 extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; 1596 1812 1597 static QGLTextureCache *qt_gl_texture_cache = 0; 1813 1814 Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache) 1598 1815 1599 1816 QGLTextureCache::QGLTextureCache() 1600 1817 : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though 1601 1818 { 1602 Q_ASSERT(qt_gl_texture_cache == 0);1603 qt_gl_texture_cache = this;1604 1605 1819 QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData); 1606 1820 QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); … … 1610 1824 QGLTextureCache::~QGLTextureCache() 1611 1825 { 1612 qt_gl_texture_cache = 0;1613 1614 1826 QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData); 1615 1827 QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); … … 1619 1831 void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) 1620 1832 { 1833 QWriteLocker locker(&m_lock); 1621 1834 if (m_cache.totalCost() + cost > m_cache.maxCost()) { 1622 1835 // the cache is full - make an attempt to remove something 1623 const QList< qint64> keys = m_cache.keys();1836 const QList<QGLTextureCacheKey> keys = m_cache.keys(); 1624 1837 int i = 0; 1625 1838 while (i < m_cache.count() … … 1631 1844 } 1632 1845 } 1633 m_cache.insert(key, texture, cost); 1846 const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; 1847 m_cache.insert(cacheKey, texture, cost); 1848 } 1849 1850 void QGLTextureCache::remove(qint64 key) 1851 { 1852 QWriteLocker locker(&m_lock); 1853 QMutexLocker groupLocker(&qt_context_groups()->m_mutex); 1854 QList<QGLContextGroup *>::const_iterator it = qt_context_groups()->m_list.constBegin(); 1855 while (it != qt_context_groups()->m_list.constEnd()) { 1856 const QGLTextureCacheKey cacheKey = {key, *it}; 1857 m_cache.remove(cacheKey); 1858 ++it; 1859 } 1634 1860 } 1635 1861 1636 1862 bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) 1637 1863 { 1638 QList<qint64> keys = m_cache.keys(); 1864 QWriteLocker locker(&m_lock); 1865 QList<QGLTextureCacheKey> keys = m_cache.keys(); 1639 1866 for (int i = 0; i < keys.size(); ++i) { 1640 1867 QGLTexture *tex = m_cache.object(keys.at(i)); … … 1650 1877 void QGLTextureCache::removeContextTextures(QGLContext* ctx) 1651 1878 { 1652 QList<qint64> keys = m_cache.keys(); 1879 QWriteLocker locker(&m_lock); 1880 QList<QGLTextureCacheKey> keys = m_cache.keys(); 1653 1881 for (int i = 0; i < keys.size(); ++i) { 1654 const qint64&key = keys.at(i);1882 const QGLTextureCacheKey &key = keys.at(i); 1655 1883 if (m_cache.object(key)->context == ctx) 1656 1884 m_cache.remove(key); 1657 1885 } 1658 }1659 1660 QGLTextureCache* QGLTextureCache::instance()1661 {1662 if (!qt_gl_texture_cache)1663 qt_gl_texture_cache = new QGLTextureCache;1664 1665 return qt_gl_texture_cache;1666 1886 } 1667 1887 … … 1672 1892 void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) 1673 1893 { 1674 // ### remove when the GL texture cache becomes thread-safe 1675 if (qApp->thread() == QThread::currentThread()) { 1676 instance()->remove(cacheKey); 1677 Q_ASSERT(instance()->getTexture(cacheKey) == 0); 1678 } 1894 qt_gl_texture_cache()->remove(cacheKey); 1679 1895 } 1680 1896 … … 1698 1914 } 1699 1915 1700 void QGLTextureCache::deleteIfEmpty() 1701 { 1702 if (instance()->size() == 0) 1703 delete instance(); 1916 QGLTextureCache *QGLTextureCache::instance() 1917 { 1918 return qt_gl_texture_cache(); 1704 1919 } 1705 1920 … … 1801 2016 1802 2017 \omitvalue CanFlipNativePixmapBindOption Used by x11 from pixmap to choose 1803 w ether or not it can bind the pixmap upside down or not.2018 whether or not it can bind the pixmap upside down or not. 1804 2019 1805 2020 \omitvalue MemoryManagedBindOption Used by paint engines to … … 1867 2082 // remove any textures cached in this context 1868 2083 QGLTextureCache::instance()->removeContextTextures(this); 1869 QGLTextureCache::deleteIfEmpty(); // ### thread safety1870 2084 1871 2085 d_ptr->group->cleanupResources(this); … … 1883 2097 { 1884 2098 Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); 2099 #ifdef glEnableVertexAttribArray 1885 2100 Q_ASSERT(glEnableVertexAttribArray); 2101 #endif 1886 2102 1887 2103 if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) … … 1896 2112 void QGLContextPrivate::syncGlState() 1897 2113 { 2114 #ifdef glEnableVertexAttribArray 1898 2115 Q_ASSERT(glEnableVertexAttribArray); 2116 #endif 1899 2117 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { 1900 2118 if (vertexAttributeArraysEnabledState[i]) … … 1907 2125 #undef ctx 1908 2126 2127 #ifdef QT_NO_EGL 2128 void QGLContextPrivate::swapRegion(const QRegion &) 2129 { 2130 Q_Q(QGLContext); 2131 q->swapBuffers(); 2132 } 2133 #endif 1909 2134 1910 2135 /*! … … 2061 2286 } 2062 2287 2288 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) 2289 QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *) 2290 { 2291 return qt_extensionFuncs; 2292 } 2293 #endif 2294 2063 2295 QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul, 2064 2296 GLenum texture_format) … … 2077 2309 QGLContext::BindOptions options) 2078 2310 { 2311 Q_Q(QGLContext); 2312 2079 2313 const qint64 key = image.cacheKey(); 2080 2314 QGLTexture *texture = textureCacheLookup(key, target); 2081 2315 if (texture) { 2082 glBindTexture(target, texture->id); 2083 return texture; 2316 if (image.paintingActive()) { 2317 // A QPainter is active on the image - take the safe route and replace the texture. 2318 q->deleteTexture(texture->id); 2319 texture = 0; 2320 } else { 2321 glBindTexture(target, texture->id); 2322 return texture; 2323 } 2084 2324 } 2085 2325 … … 2127 2367 2128 2368 #ifdef QGL_BIND_TEXTURE_DEBUG 2129 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x \n",2130 image.width(), image.height(), internalFormat, int(options) );2369 printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n", 2370 image.width(), image.height(), internalFormat, int(options), key); 2131 2371 QTime time; 2132 2372 time.start(); … … 2172 2412 && (options & QGLContext::MipmapBindOption)) 2173 2413 { 2174 #ifdef QGL_BIND_TEXTURE_DEBUG2175 printf(" - generating mipmaps (%d ms)\n", time.elapsed());2176 #endif2177 2414 #if !defined(QT_OPENGL_ES_2) 2178 2415 glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); … … 2188 2425 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption 2189 2426 ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); 2427 #ifdef QGL_BIND_TEXTURE_DEBUG 2428 printf(" - generating mipmaps (%d ms)\n", time.elapsed()); 2429 #endif 2190 2430 } else { 2191 2431 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, filtering); … … 2212 2452 img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied); 2213 2453 #ifdef QGL_BIND_TEXTURE_DEBUG 2214 printf(" - convert ingARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());2454 printf(" - converted ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed()); 2215 2455 #endif 2216 2456 } … … 2220 2460 img = img.convertToFormat(target_format = QImage::Format_ARGB32); 2221 2461 #ifdef QGL_BIND_TEXTURE_DEBUG 2222 printf(" - convert ingARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());2462 printf(" - converted ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed()); 2223 2463 #endif 2224 2464 } … … 2237 2477 : QImage::Format_ARGB32); 2238 2478 #ifdef QGL_BIND_TEXTURE_DEBUG 2239 printf(" - convert ingto 32-bit alpha format (%d ms)\n", time.elapsed());2479 printf(" - converted to 32-bit alpha format (%d ms)\n", time.elapsed()); 2240 2480 #endif 2241 2481 } else { 2242 2482 img = img.convertToFormat(QImage::Format_RGB32); 2243 2483 #ifdef QGL_BIND_TEXTURE_DEBUG 2244 printf(" - convert ingto 32-bit (%d ms)\n", time.elapsed());2484 printf(" - converted to 32-bit (%d ms)\n", time.elapsed()); 2245 2485 #endif 2246 2486 } … … 2248 2488 2249 2489 if (options & QGLContext::InvertedYBindOption) { 2250 #ifdef QGL_BIND_TEXTURE_DEBUG2251 printf(" - flipping bits over y (%d ms)\n", time.elapsed());2252 #endif2253 2490 if (img.isDetached()) { 2254 2491 int ipl = img.bytesPerLine() / 4; … … 2267 2504 img = img.mirrored(); 2268 2505 } 2506 #ifdef QGL_BIND_TEXTURE_DEBUG 2507 printf(" - flipped bits over y (%d ms)\n", time.elapsed()); 2508 #endif 2269 2509 } 2270 2510 2271 2511 if (externalFormat == GL_RGBA) { 2272 #ifdef QGL_BIND_TEXTURE_DEBUG2273 printf(" - doing byte swapping (%d ms)\n", time.elapsed());2274 #endif2275 2512 // The only case where we end up with a depth different from 2276 2513 // 32 in the switch above is for the RGB16 case, where we set … … 2278 2515 Q_ASSERT(img.depth() == 32); 2279 2516 qgl_byteSwapImage(img, pixel_type); 2517 #ifdef QGL_BIND_TEXTURE_DEBUG 2518 printf(" - did byte swapping (%d ms)\n", time.elapsed()); 2519 #endif 2280 2520 } 2281 2521 #ifdef QT_OPENGL_ES … … 2299 2539 GLenum error = glGetError(); 2300 2540 if (error != GL_NO_ERROR) { 2301 qWarning(" - texture upload failed, error code 0x%x \n", error);2541 qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target); 2302 2542 } 2303 2543 #endif … … 2306 2546 static int totalUploadTime = 0; 2307 2547 totalUploadTime += time.elapsed(); 2308 printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime);2548 printf(" - upload done in %d ms, (accumulated: %d ms)\n", time.elapsed(), totalUploadTime); 2309 2549 #endif 2310 2550 … … 2321 2561 { 2322 2562 Q_Q(QGLContext); 2323 QGLTexture *texture = QGLTextureCache::instance()->getTexture( key);2563 QGLTexture *texture = QGLTextureCache::instance()->getTexture(q, key); 2324 2564 if (texture && texture->target == target 2325 2565 && (texture->context == q || QGLContext::areSharing(q, texture->context))) … … 2336 2576 Q_Q(QGLContext); 2337 2577 QPixmapData *pd = pixmap.pixmapData(); 2338 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)2578 #if !defined(QT_OPENGL_ES_1) 2339 2579 if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { 2340 2580 const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd); … … 2347 2587 #else 2348 2588 Q_UNUSED(pd); 2349 Q_UNUSED(q);2350 2589 #endif 2351 2590 … … 2353 2592 QGLTexture *texture = textureCacheLookup(key, target); 2354 2593 if (texture) { 2355 glBindTexture(target, texture->id); 2356 return texture; 2594 if (pixmap.paintingActive()) { 2595 // A QPainter is active on the pixmap - take the safe route and replace the texture. 2596 q->deleteTexture(texture->id); 2597 texture = 0; 2598 } else { 2599 glBindTexture(target, texture->id); 2600 return texture; 2601 } 2357 2602 } 2358 2603 … … 2361 2606 const QX11Info *xinfo = qt_x11Info(paintDevice); 2362 2607 if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType 2363 && xinfo && xinfo->screen() == pixmap.x11Info().screen()) 2608 && xinfo && xinfo->screen() == pixmap.x11Info().screen() 2609 && target == GL_TEXTURE_2D) 2364 2610 { 2365 texture = bindTextureFromNativePixmap(pd, key, options); 2366 if (texture) { 2367 texture->options |= QGLContext::MemoryManagedBindOption; 2368 texture->boundPixmap = pd; 2369 boundPixmaps.insert(pd, QPixmap(pixmap)); 2611 if (!workaround_brokenTextureFromPixmap_init) { 2612 workaround_brokenTextureFromPixmap_init = true; 2613 2614 const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION))); 2615 const int pos = versionString.indexOf("NVIDIA "); 2616 2617 if (pos >= 0) { 2618 const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); 2619 2620 if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) 2621 workaround_brokenTextureFromPixmap = true; 2622 } 2370 2623 } 2371 } 2372 #endif 2373 2374 if (!texture) 2375 texture = bindTexture(pixmap.toImage(), target, format, key, options); 2624 2625 if (!workaround_brokenTextureFromPixmap) { 2626 texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); 2627 if (texture) { 2628 texture->options |= QGLContext::MemoryManagedBindOption; 2629 texture->boundPixmap = pd; 2630 boundPixmaps.insert(pd, QPixmap(pixmap)); 2631 } 2632 } 2633 } 2634 #endif 2635 2636 if (!texture) { 2637 QImage image = pixmap.toImage(); 2638 // If the system depth is 16 and the pixmap doesn't have an alpha channel 2639 // then we convert it to RGB16 in the hope that it gets uploaded as a 16 2640 // bit texture which is much faster to access than a 32-bit one. 2641 if (pixmap.depth() == 16 && !image.hasAlphaChannel() ) 2642 image = image.convertToFormat(QImage::Format_RGB16); 2643 texture = bindTexture(image, target, format, key, options); 2644 } 2376 2645 // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null 2377 2646 Q_ASSERT(texture); … … 2466 2735 2467 2736 Q_D(QGLContext); 2468 QGLTexture *texture = d->bindTexture(image, target, format, false,options);2737 QGLTexture *texture = d->bindTexture(image, target, format, options); 2469 2738 return texture->id; 2470 2739 } … … 2478 2747 2479 2748 Q_D(QGLContext); 2480 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false,DefaultBindOption);2749 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption); 2481 2750 return texture->id; 2482 2751 } … … 2490 2759 2491 2760 Q_D(QGLContext); 2492 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false,options);2761 QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options); 2493 2762 return texture->id; 2494 2763 } … … 2588 2857 #endif 2589 2858 2590 void qt_add_rect_to_array(const QRectF &r, q_vertexType*array)2859 void qt_add_rect_to_array(const QRectF &r, GLfloat *array) 2591 2860 { 2592 2861 qreal left = r.left(); … … 2595 2864 qreal bottom = r.bottom(); 2596 2865 2597 array[0] = f2vt(left);2598 array[1] = f2vt(top);2599 array[2] = f2vt(right);2600 array[3] = f2vt(top);2601 array[4] = f2vt(right);2602 array[5] = f2vt(bottom);2603 array[6] = f2vt(left);2604 array[7] = f2vt(bottom);2605 } 2606 2607 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType*array)2608 { 2609 array[0] = f2vt(x1);2610 array[1] = f2vt(y1);2611 array[2] = f2vt(x2);2612 array[3] = f2vt(y1);2613 array[4] = f2vt(x2);2614 array[5] = f2vt(y2);2615 array[6] = f2vt(x1);2616 array[7] = f2vt(y2);2866 array[0] = left; 2867 array[1] = top; 2868 array[2] = right; 2869 array[3] = top; 2870 array[4] = right; 2871 array[5] = bottom; 2872 array[6] = left; 2873 array[7] = bottom; 2874 } 2875 2876 void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array) 2877 { 2878 array[0] = x1; 2879 array[1] = y1; 2880 array[2] = x2; 2881 array[3] = y1; 2882 array[4] = x2; 2883 array[5] = y2; 2884 array[6] = x1; 2885 array[7] = y2; 2617 2886 } 2618 2887 … … 2621 2890 static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) 2622 2891 { 2623 q_vertexType tx = f2vt(1);2624 q_vertexType ty = f2vt(1);2892 GLfloat tx = 1.0f; 2893 GLfloat ty = 1.0f; 2625 2894 2626 2895 #ifdef QT_OPENGL_ES … … 2635 2904 } 2636 2905 2637 tx = f2vt(textureWidth);2638 ty = f2vt(textureHeight);2639 } 2640 #endif 2641 2642 q_vertexTypetexCoordArray[4*2] = {2906 tx = GLfloat(textureWidth); 2907 ty = GLfloat(textureHeight); 2908 } 2909 #endif 2910 2911 GLfloat texCoordArray[4*2] = { 2643 2912 0, ty, tx, ty, tx, 0, 0, 0 2644 2913 }; 2645 2914 2646 q_vertexTypevertexArray[4*2];2915 GLfloat vertexArray[4*2]; 2647 2916 qt_add_rect_to_array(target, vertexArray); 2648 2917 2649 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);2650 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);2918 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 2919 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); 2651 2920 2652 2921 glEnableClientState(GL_VERTEX_ARRAY); … … 2663 2932 \since 4.4 2664 2933 2665 Draws the given texture, \a textureId, to the given target rectangle, 2666 \a target, in OpenGL model space. The \a textureTarget should be a 2D 2667 texture target. 2668 2669 \note This function is not supported under OpenGL/ES 2.0. 2934 This function supports the following use cases: 2935 2936 \list 2937 \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, 2938 to the given target rectangle, \a target, in OpenGL model space. The 2939 \a textureTarget should be a 2D texture target. 2940 \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a 2941 beginNativePainting / endNativePainting block, and uses the 2942 engine with type QPaintEngine::OpenGL2, the function will draw the given 2943 texture, \a textureId, to the given target rectangle, \a target, 2944 respecting the current painter state. This will let you draw a texture 2945 with the clip, transform, render hints, and composition mode set by the 2946 painter. Note that the texture target needs to be GL_TEXTURE_2D for this 2947 use case, and that this is the only supported use case under OpenGL ES 2.x. 2948 \endlist 2949 2670 2950 */ 2671 2951 void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) 2672 2952 { 2953 #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) 2954 if (d_ptr->active_engine && 2955 d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { 2956 QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); 2957 if (!eng->isNativePaintingActive()) { 2958 QRectF src(0, 0, target.width(), target.height()); 2959 QSize size(target.width(), target.height()); 2960 if (eng->drawTexture(target, textureId, size, src)) 2961 return; 2962 } 2963 } 2964 #endif 2965 2673 2966 #ifndef QT_OPENGL_ES_2 2674 2967 #ifdef QT_OPENGL_ES … … 2699 2992 Q_UNUSED(textureId); 2700 2993 Q_UNUSED(textureTarget); 2701 qWarning("drawTexture( const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");2994 qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); 2702 2995 #endif 2703 2996 } … … 2714 3007 \since 4.4 2715 3008 2716 Draws the given texture at the given \a point in OpenGL model 2717 space. The \a textureTarget should be a 2D texture target. 2718 2719 \note This function is not supported under OpenGL/ES. 3009 This function supports the following use cases: 3010 3011 \list 3012 \i By default it draws the given texture, \a textureId, 3013 at the given \a point in OpenGL model space. The 3014 \a textureTarget should be a 2D texture target. 3015 \i If a painter is active, not inside a 3016 beginNativePainting / endNativePainting block, and uses the 3017 engine with type QPaintEngine::OpenGL2, the function will draw the given 3018 texture, \a textureId, at the given \a point, 3019 respecting the current painter state. This will let you draw a texture 3020 with the clip, transform, render hints, and composition mode set by the 3021 painter. Note that the texture target needs to be GL_TEXTURE_2D for this 3022 use case. 3023 \endlist 3024 3025 \note This function is not supported under any version of OpenGL ES. 2720 3026 */ 2721 3027 void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) 2722 3028 { 2723 // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that2724 3029 #ifdef QT_OPENGL_ES 2725 3030 Q_UNUSED(point); … … 2728 3033 qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); 2729 3034 #else 3035 2730 3036 const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); 2731 3037 GLint oldTexture; … … 2740 3046 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); 2741 3047 glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); 3048 3049 if (d_ptr->active_engine && 3050 d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { 3051 QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); 3052 if (!eng->isNativePaintingActive()) { 3053 QRectF dest(point, QSizeF(textureWidth, textureHeight)); 3054 QRectF src(0, 0, textureWidth, textureHeight); 3055 QSize size(textureWidth, textureHeight); 3056 if (eng->drawTexture(dest, textureId, size, src)) 3057 return; 3058 } 3059 } 2742 3060 2743 3061 qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); … … 3199 3517 \sa QGLWidget::renderText() 3200 3518 */ 3519 3201 3520 3202 3521 … … 3321 3640 \l{Overpainting Example}{Overpainting} example. 3322 3641 3642 \section1 Threading 3643 3644 It is possible to render into a QGLWidget from another thread, but it 3645 requires that all access to the GL context is safe guarded. The Qt GUI 3646 thread will try to use the context in resizeEvent and paintEvent, so in 3647 order for threaded rendering using a GL widget to work, these functions 3648 need to be intercepted in the GUI thread and handled accordingly in the 3649 application. 3650 3323 3651 \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other 3324 3652 countries.} … … 3448 3776 #endif 3449 3777 delete d->glcx; 3450 #if defined(Q_WGL) 3778 d->glcx = 0; 3779 #if defined(Q_WS_WIN) 3451 3780 delete d->olcx; 3781 d->olcx = 0; 3452 3782 #endif 3453 3783 #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT) … … 3851 4181 } 3852 4182 3853 #if defined(QT_OPENGL_ES)4183 #ifndef QT_NO_EGL 3854 4184 // A re-parent is likely to destroy the X11 window and re-create it. It is important 3855 4185 // that we free the EGL surface _before_ the winID changes - otherwise we can leak. … … 3860 4190 // The window may have been re-created during re-parent or state change - if so, the EGL 3861 4191 // surface will need to be re-created. 3862 d->recreateEglSurface( false);4192 d->recreateEglSurface(); 3863 4193 } 3864 4194 #endif … … 3902 4232 # endif 3903 4233 } 4234 #elif defined(Q_OS_SYMBIAN) 4235 // prevents errors on some systems, where we get a flush to a 4236 // hidden widget 4237 if (e->type() == QEvent::Hide) { 4238 makeCurrent(); 4239 glFinish(); 4240 doneCurrent(); 4241 } else if (e->type() == QEvent::ParentChange) { 4242 // if we've reparented a window that has the current context 4243 // bound, we need to rebind that context to the new window id 4244 if (d->glcx == QGLContext::currentContext()) 4245 makeCurrent(); 4246 4247 if (testAttribute(Qt::WA_TranslucentBackground)) 4248 setContext(new QGLContext(d->glcx->requestedFormat(), this)); 4249 } 4250 4251 // A re-parent is likely to destroy the Symbian window and re-create it. It is important 4252 // that we free the EGL surface _before_ the winID changes - otherwise we can leak. 4253 if (e->type() == QEvent::ParentAboutToChange) 4254 d->glcx->d_func()->destroyEglSurfaceForDevice(); 4255 4256 if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) { 4257 // The window may have been re-created during re-parent or state change - if so, the EGL 4258 // surface will need to be re-created. 4259 d->recreateEglSurface(); 4260 } 4261 3904 4262 #endif 3905 4263 … … 4109 4467 if (!isValid()) 4110 4468 return; 4469 #ifdef Q_OS_SYMBIAN 4470 // Crashes on Symbian if trying to render to invisible surfaces 4471 if (!isVisible() && d->glcx->device()->devType() == QInternal::Widget) 4472 return; 4473 #endif 4111 4474 makeCurrent(); 4112 4475 #ifndef QT_OPENGL_ES … … 4766 5129 \since 4.4 4767 5130 4768 Draws the given texture, \a textureId to the given target rectangle, 4769 \a target, in OpenGL model space. The \a textureTarget should be a 2D 4770 texture target. 4771 4772 Equivalent to the corresponding QGLContext::drawTexture(). 5131 Calls the corresponding QGLContext::drawTexture() with 5132 \a target, \a textureId, and \a textureTarget for this 5133 widget's context. 4773 5134 */ 4774 5135 void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) … … 4790 5151 \since 4.4 4791 5152 4792 Draws the given texture, \a textureId, at the given \a point in OpenGL 4793 model space. The \a textureTarget should be a 2D texture target. 4794 4795 Equivalent to the corresponding QGLContext::drawTexture(). 5153 Calls the corresponding QGLContext::drawTexture() with 5154 \a point, \a textureId, and \a textureTarget for this 5155 widget's context. 4796 5156 */ 4797 5157 void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) … … 4810 5170 #endif 4811 5171 4812 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)5172 #ifndef QT_OPENGL_ES_1 4813 5173 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) 4814 5174 #endif … … 4820 5180 Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() 4821 5181 { 4822 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)5182 #if defined(QT_OPENGL_ES_1) 4823 5183 return qt_gl_engine(); 4824 5184 #elif defined(QT_OPENGL_ES_2) … … 4924 5284 if (extensions.match("GL_ARB_fragment_shader")) 4925 5285 glExtensions |= FragmentShader; 5286 if (extensions.match("GL_ARB_shader_objects")) 5287 glExtensions |= FragmentShader; 4926 5288 if (extensions.match("GL_ARB_texture_mirrored_repeat")) 4927 5289 glExtensions |= MirroredRepeat; … … 4938 5300 if (extensions.match("GL_ARB_pixel_buffer_object")) 4939 5301 glExtensions |= PixelBufferObject; 5302 if (extensions.match("GL_IMG_texture_format_BGRA8888")) 5303 glExtensions |= BGRATextureFormat; 4940 5304 #if defined(QT_OPENGL_ES_2) 4941 5305 glExtensions |= FramebufferObject; … … 4943 5307 glExtensions |= FragmentShader; 4944 5308 #endif 4945 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)5309 #if defined(QT_OPENGL_ES_1) 4946 5310 if (extensions.match("GL_OES_framebuffer_object")) 4947 5311 glExtensions |= FramebufferObject; … … 4950 5314 if (extensions.match("GL_OES_packed_depth_stencil")) 4951 5315 glExtensions |= PackedDepthStencil; 5316 if (extensions.match("GL_OES_element_index_uint")) 5317 glExtensions |= ElementIndexUint; 5318 if (extensions.match("GL_OES_depth24")) 5319 glExtensions |= Depth24; 5320 #else 5321 glExtensions |= ElementIndexUint; 4952 5322 #endif 4953 5323 if (extensions.match("GL_ARB_framebuffer_object")) { … … 4969 5339 } 4970 5340 5341 5342 class QGLDefaultExtensions 5343 { 5344 public: 5345 QGLDefaultExtensions() { 5346 QGLTemporaryContext tempContext; 5347 extensions = QGLExtensions::currentContextExtensions(); 5348 } 5349 5350 QGLExtensions::Extensions extensions; 5351 }; 5352 5353 Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions) 5354 4971 5355 /* 4972 5356 Returns the GL extensions for the current QGLContext. If there is no … … 4976 5360 QGLExtensions::Extensions QGLExtensions::glExtensions() 4977 5361 { 4978 QGLTemporaryContext *tmpContext = 0; 4979 static bool cachedDefault = false; 4980 static Extensions defaultExtensions = 0; 5362 Extensions extensionFlags = 0; 4981 5363 QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext()); 4982 5364 … … 4985 5367 4986 5368 if (!currentCtx) { 4987 if (cachedDefault) { 4988 return defaultExtensions; 4989 } else { 4990 tmpContext = new QGLTemporaryContext; 4991 cachedDefault = true; 4992 } 4993 } 4994 4995 Extensions extensionFlags = currentContextExtensions(); 4996 if (currentCtx) { 5369 extensionFlags = qtDefaultExtensions()->extensions; 5370 } else { 5371 extensionFlags = currentContextExtensions(); 4997 5372 currentCtx->d_func()->extension_flags_cached = true; 4998 5373 currentCtx->d_func()->extension_flags = extensionFlags; 4999 } else { 5000 defaultExtensions = extensionFlags; 5001 } 5002 5003 if (tmpContext) 5004 delete tmpContext; 5005 5374 } 5006 5375 return extensionFlags; 5007 5376 } … … 5038 5407 { 5039 5408 if (qt_gl_lib_name()->isNull()) { 5040 #if defined(Q_WS_X11) || defined(Q_WS_QWS) 5409 #ifdef Q_WS_MAC 5410 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); 5411 #else 5412 # if defined(QT_OPENGL_ES_1) 5413 return QLatin1String("GLES_CM"); 5414 # elif defined(QT_OPENGL_ES_2) 5415 return QLatin1String("GLESv2"); 5416 # else 5041 5417 return QLatin1String("GL"); 5042 #else // Q_WS_MAC 5043 return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); 5044 #endif 5418 # endif 5419 #endif // defined Q_WS_MAC 5045 5420 } 5046 5421 return *qt_gl_lib_name(); -
trunk/src/opengl/qgl.h
r651 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) … … 58 58 # include <OpenGL/gl.h> 59 59 # include <OpenGL/glu.h> 60 #elif defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)60 #elif defined(QT_OPENGL_ES_1) 61 61 # include <GLES/gl.h> 62 62 #ifndef GL_DOUBLE … … 145 145 HasOverlay = 0x0100, 146 146 SampleBuffers = 0x0200, 147 DeprecatedFunctions = 0x0400, 147 148 SingleBuffer = DoubleBuffer << 16, 148 149 NoDepthBuffer = DepthBuffer << 16, … … 154 155 IndirectRendering = DirectRendering << 16, 155 156 NoOverlay = HasOverlay << 16, 156 NoSampleBuffers = SampleBuffers << 16 157 NoSampleBuffers = SampleBuffers << 16, 158 NoDeprecatedFunctions = DeprecatedFunctions << 16 157 159 }; 158 160 Q_DECLARE_FLAGS(FormatOptions, FormatOption) … … 236 238 static bool hasOpenGLOverlays(); 237 239 238 enum OpenGLVersionFlag { 240 void setVersion(int major, int minor); 241 int majorVersion() const; 242 int minorVersion() const; 243 244 enum OpenGLContextProfile { 245 NoProfile, 246 CoreProfile, 247 CompatibilityProfile 248 }; 249 250 void setProfile(OpenGLContextProfile profile); 251 OpenGLContextProfile profile() const; 252 253 enum OpenGLVersionFlag { 239 254 OpenGL_Version_None = 0x00000000, 240 255 OpenGL_Version_1_1 = 0x00000001, … … 250 265 OpenGL_ES_CommonLite_Version_1_1 = 0x00000400, 251 266 OpenGL_ES_Version_2_0 = 0x00000800, 252 OpenGL_Version_3_0 = 0x00001000 267 OpenGL_Version_3_0 = 0x00001000, 268 OpenGL_Version_3_1 = 0x00002000, 269 OpenGL_Version_3_2 = 0x00004000, 270 OpenGL_Version_3_3 = 0x00008000, 271 OpenGL_Version_4_0 = 0x00010000 253 272 }; 254 273 Q_DECLARE_FLAGS(OpenGLVersionFlags, OpenGLVersionFlag) … … 263 282 friend Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); 264 283 friend Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); 284 #ifndef QT_NO_DEBUG_STREAM 285 friend Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); 286 #endif 265 287 }; 266 288 … … 269 291 Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); 270 292 Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); 293 294 #ifndef QT_NO_DEBUG_STREAM 295 Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); 296 #endif 271 297 272 298 class Q_OPENGL_EXPORT QGLContext … … 360 386 virtual int choosePixelFormat(void* pfd, HDC pdc); 361 387 #endif 362 #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)388 #if defined(Q_WS_X11) && defined(QT_NO_EGL) 363 389 virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1); 364 390 virtual void* chooseVisual(); … … 403 429 friend class QGLPixmapBlurFilter; 404 430 friend class QGLExtensions; 431 friend class QGLTexture; 405 432 friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags(); 406 433 #ifdef Q_WS_MAC … … 415 442 friend class QGLFBOGLPaintDevice; 416 443 friend class QGLPaintDevice; 444 friend class QGLWidgetGLPaintDevice; 417 445 friend class QX11GLPixmapData; 446 friend class QX11GLSharedContexts; 418 447 private: 419 448 Q_DISABLE_COPY(QGLContext) -
trunk/src/opengl/qgl_egl.cpp
r651 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) … … 41 41 42 42 #include <QtOpenGL/qgl.h> 43 #include <QtOpenGL/qglpixelbuffer.h> 43 44 #include "qgl_p.h" 44 45 #include "qgl_egl_p.h" 46 #include "qglpixelbuffer_p.h" 47 48 #ifdef Q_WS_X11 49 #include <QtGui/private/qpixmap_x11_p.h> 50 #endif 45 51 46 52 QT_BEGIN_NAMESPACE 47 53 48 // Set device configuration attributes from a QGLFormat instance. 49 void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f) 50 { 51 if (deviceType == QInternal::Pixmap || deviceType == QInternal::Image) 52 props.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT); 53 else if (deviceType == QInternal::Pbuffer) 54 props.setValue(EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); 55 else 56 props.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); 57 58 // Set the pixel format to that contained in the QGLFormat 59 // if the system hasn't already chosen a fixed format to 60 // match the pixmap, widget, etc. 61 if (props.value(EGL_RED_SIZE) == 0 || f.redBufferSize() != -1) 62 props.setValue(EGL_RED_SIZE, f.redBufferSize() == -1 ? 1 : f.redBufferSize()); 63 if (props.value(EGL_GREEN_SIZE) == 0 || f.greenBufferSize() != -1) 64 props.setValue(EGL_GREEN_SIZE, f.greenBufferSize() == -1 ? 1 : f.greenBufferSize()); 65 if (props.value(EGL_BLUE_SIZE) == 0 || f.blueBufferSize() != -1) 66 props.setValue(EGL_BLUE_SIZE, f.blueBufferSize() == -1 ? 1 : f.blueBufferSize()); 67 if (f.alpha()) { 68 if (props.value(EGL_ALPHA_SIZE) == 0 || f.alphaBufferSize() != -1) 69 props.setValue(EGL_ALPHA_SIZE, f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize()); 70 } 71 72 if (f.depth()) 73 props.setValue(EGL_DEPTH_SIZE, f.depthBufferSize() == -1 ? 1 : f.depthBufferSize()); 74 if (f.stencil()) 75 props.setValue(EGL_STENCIL_SIZE, f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize()); 76 if (f.sampleBuffers()) { 77 props.setValue(EGL_SAMPLE_BUFFERS, 1); 78 props.setValue(EGL_SAMPLES, f.samples() == -1 ? 1 : f.samples()); 79 } else { 80 props.setValue(EGL_SAMPLE_BUFFERS, 0); 81 } 82 if (deviceType == QInternal::Widget) 83 props.setValue(EGL_LEVEL, f.plane()); 54 void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat) 55 { 56 int redSize = glFormat.redBufferSize(); 57 int greenSize = glFormat.greenBufferSize(); 58 int blueSize = glFormat.blueBufferSize(); 59 int alphaSize = glFormat.alphaBufferSize(); 60 int depthSize = glFormat.depthBufferSize(); 61 int stencilSize = glFormat.stencilBufferSize(); 62 int sampleCount = glFormat.samples(); 63 64 // QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that 65 // type has been requested. So we must check QGLFormat's booleans too if size is -1: 66 if (glFormat.alpha() && alphaSize <= 0) 67 alphaSize = 1; 68 if (glFormat.depth() && depthSize <= 0) 69 depthSize = 1; 70 if (glFormat.stencil() && stencilSize <= 0) 71 stencilSize = 1; 72 if (glFormat.sampleBuffers() && sampleCount <= 0) 73 sampleCount = 1; 74 75 // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide 76 // the best performance. The EGL config selection algorithm is a bit stange in this regard: 77 // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard 78 // 32-bit configs completely from the selection. So it then comes to the sorting algorithm. 79 // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort 80 // order is special and described as "by larger _total_ number of color bits.". So EGL will 81 // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on 82 // to say "If the requested number of bits in attrib_list for a particular component is 0, 83 // then the number of bits for that component is not considered". This part of the spec also 84 // seems to imply that setting the red/green/blue bits to zero means none of the components 85 // are considered and EGL disregards the entire sorting rule. It then looks to the next 86 // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being 87 // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are 88 // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, 89 // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that 90 // if the application sets the red/green/blue size to 5/6/5 on the QGLFormat, they will 91 // probably get a 32-bit config, even when there's an RGB565 config available. Oh well. 92 93 // Now normalize the values so -1 becomes 0 94 redSize = redSize > 0 ? redSize : 0; 95 greenSize = greenSize > 0 ? greenSize : 0; 96 blueSize = blueSize > 0 ? blueSize : 0; 97 alphaSize = alphaSize > 0 ? alphaSize : 0; 98 depthSize = depthSize > 0 ? depthSize : 0; 99 stencilSize = stencilSize > 0 ? stencilSize : 0; 100 sampleCount = sampleCount > 0 ? sampleCount : 0; 101 102 eglProperties.setValue(EGL_RED_SIZE, redSize); 103 eglProperties.setValue(EGL_GREEN_SIZE, greenSize); 104 eglProperties.setValue(EGL_BLUE_SIZE, blueSize); 105 eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize); 106 eglProperties.setValue(EGL_DEPTH_SIZE, depthSize); 107 eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize); 108 eglProperties.setValue(EGL_SAMPLES, sampleCount); 109 eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0); 84 110 } 85 111 86 112 // Updates "format" with the parameters of the selected configuration. 87 void qt_egl_update_format(const QEglContext& context, QGLFormat& format) 88 { 89 EGLint value = 0; 90 91 if (context.configAttrib(EGL_RED_SIZE, &value)) 92 format.setRedBufferSize(value); 93 if (context.configAttrib(EGL_GREEN_SIZE, &value)) 94 format.setGreenBufferSize(value); 95 if (context.configAttrib(EGL_BLUE_SIZE, &value)) 96 format.setBlueBufferSize(value); 97 if (context.configAttrib(EGL_ALPHA_SIZE, &value)) { 98 format.setAlpha(value != 0); 99 if (format.alpha()) 100 format.setAlphaBufferSize(value); 101 } 102 103 if (context.configAttrib(EGL_DEPTH_SIZE, &value)) { 104 format.setDepth(value != 0); 105 if (format.depth()) 106 format.setDepthBufferSize(value); 107 } 108 109 if (context.configAttrib(EGL_LEVEL, &value)) 110 format.setPlane(value); 111 112 if (context.configAttrib(EGL_SAMPLE_BUFFERS, &value)) { 113 format.setSampleBuffers(value != 0); 114 if (format.sampleBuffers()) { 115 context.configAttrib(EGL_SAMPLES, &value); 116 format.setSamples(value); 117 } 118 } 119 120 if (context.configAttrib(EGL_STENCIL_SIZE, &value)) { 121 format.setStencil(value != 0); 122 if (format.stencil()) 123 format.setStencilBufferSize(value); 124 } 113 void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config) 114 { 115 EGLint redSize = 0; 116 EGLint greenSize = 0; 117 EGLint blueSize = 0; 118 EGLint alphaSize = 0; 119 EGLint depthSize = 0; 120 EGLint stencilSize = 0; 121 EGLint sampleCount = 0; 122 EGLint level = 0; 123 124 EGLDisplay display = QEgl::display(); 125 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); 126 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); 127 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); 128 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); 129 eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); 130 eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); 131 eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); 132 eglGetConfigAttrib(display, config, EGL_LEVEL, &level); 133 134 format.setRedBufferSize(redSize); 135 format.setGreenBufferSize(greenSize); 136 format.setBlueBufferSize(blueSize); 137 format.setAlphaBufferSize(alphaSize); 138 format.setDepthBufferSize(depthSize); 139 format.setStencilBufferSize(stencilSize); 140 format.setSamples(sampleCount); 141 format.setPlane(level); 142 format.setDirectRendering(true); // All EGL contexts are direct-rendered 143 format.setRgba(true); // EGL doesn't support colour index rendering 144 format.setStereo(false); // EGL doesn't support stereo buffers 145 format.setAccumBufferSize(0); // EGL doesn't support accululation buffers 146 format.setDoubleBuffer(true); // We don't support single buffered EGL contexts 125 147 126 148 // Clear the EGL error state because some of the above may 127 149 // have errored out because the attribute is not applicable 128 150 // to the surface type. Such errors don't matter. 129 context.clearError();151 eglGetError(); 130 152 } 131 153 … … 142 164 d->cleanup(); 143 165 doneCurrent(); 144 if (d->eglContext ) {166 if (d->eglContext && d->ownsEglContext) { 145 167 d->destroyEglSurfaceForDevice(); 146 168 delete d->eglContext; 147 169 } 170 d->ownsEglContext = false; 148 171 d->eglContext = 0; 149 172 d->eglSurface = EGL_NO_SURFACE; … … 159 182 { 160 183 Q_D(QGLContext); 161 if (!d->valid || !d->eglContext || d->eglSurface == EGL_NO_SURFACE) {184 if (!d->valid || !d->eglContext || d->eglSurfaceForDevice() == EGL_NO_SURFACE) { 162 185 qWarning("QGLContext::makeCurrent(): Cannot make invalid context current"); 163 186 return; 164 187 } 165 188 166 if (d->eglContext->makeCurrent(d->eglSurface ))189 if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) { 167 190 QGLContextPrivate::setCurrentContext(this); 191 if (!d->workaroundsCached) { 192 d->workaroundsCached = true; 193 const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); 194 if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) { 195 // PowerVR MBX/SGX chips needs to clear all buffers when starting to render 196 // a new frame, otherwise there will be a performance penalty to pay for 197 // each frame. 198 d->workaround_needsFullClearOnEveryFrame = true; 199 200 // Older PowerVR SGX drivers (like the one in the N900) have a 201 // bug which prevents glCopyTexSubImage2D() to work with a POT 202 // or GL_ALPHA texture bound to an FBO. The only way to 203 // identify that driver is to check the EGL version number for it. 204 const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION); 205 if (egl_version && strstr(egl_version, "1.3")) 206 d->workaround_brokenFBOReadBack = true; 207 else if (egl_version && strstr(egl_version, "1.4")) 208 d->workaround_brokenTexSubImage = true; 209 } 210 } 211 } 168 212 } 169 213 … … 184 228 return; 185 229 186 d->eglContext->swapBuffers(d->eglSurface );230 d->eglContext->swapBuffers(d->eglSurfaceForDevice()); 187 231 } 188 232 … … 190 234 { 191 235 if (eglSurface != EGL_NO_SURFACE) { 236 #if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN) 237 // Make sure we don't call eglDestroySurface on a surface which 238 // was created for a different winId. This applies only to QGLWidget 239 // paint device, so make sure this is the one we're operating on 240 // (as opposed to a QGLWindowSurface use case). 241 if (paintDevice && paintDevice->devType() == QInternal::Widget) { 242 QWidget *w = static_cast<QWidget *>(paintDevice); 243 if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) { 244 if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) { 245 qWarning("WARNING: Potential EGL surface leak! Not destroying surface."); 246 eglSurface = EGL_NO_SURFACE; 247 return; 248 } 249 } 250 } 251 #endif 252 eglDestroySurface(eglContext->display(), eglSurface); 253 eglSurface = EGL_NO_SURFACE; 254 } 255 } 256 257 EGLSurface QGLContextPrivate::eglSurfaceForDevice() const 258 { 259 // If a QPixmapData had to create the QGLContext, we don't have a paintDevice 260 if (!paintDevice) 261 return eglSurface; 262 192 263 #ifdef Q_WS_X11 193 // Make sure we don't call eglDestroySurface on a surface which 194 // was created for a different winId: 195 if (paintDevice->devType() == QInternal::Widget) { 196 QGLWidget* w = static_cast<QGLWidget*>(paintDevice); 197 198 if (w->d_func()->eglSurfaceWindowId == w->winId()) 199 eglDestroySurface(eglContext->display(), eglSurface); 200 else 201 qWarning("WARNING: Potential EGL surface leak!"); 202 } else 264 if (paintDevice->devType() == QInternal::Pixmap) { 265 QPixmapData *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data(); 266 if (pmd->classId() == QPixmapData::X11Class) { 267 QX11PixmapData* x11PixmapData = static_cast<QX11PixmapData*>(pmd); 268 return (EGLSurface)x11PixmapData->gl_surface; 269 } 270 } 203 271 #endif 204 eglDestroySurface(eglContext->display(), eglSurface); 205 eglSurface = EGL_NO_SURFACE; 206 } 272 273 if (paintDevice->devType() == QInternal::Pbuffer) { 274 QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice); 275 return pbuf->d_func()->pbuf; 276 } 277 278 return eglSurface; 279 } 280 281 void QGLContextPrivate::swapRegion(const QRegion ®ion) 282 { 283 if (!valid || !eglContext) 284 return; 285 286 eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), ®ion); 207 287 } 208 288 -
trunk/src/opengl/qgl_egl_p.h
r651 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) … … 55 55 56 56 #include <QtGui/private/qegl_p.h> 57 #include <QtGui/private/qeglcontext_p.h> 58 #include <QtGui/private/qeglproperties_p.h> 57 59 58 60 QT_BEGIN_NAMESPACE … … 60 62 class QGLFormat; 61 63 62 void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f); 63 void qt_egl_update_format(const QEglContext& context, QGLFormat& format); 64 void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device); 64 void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format); 65 void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config); 65 66 66 67 QT_END_NAMESPACE -
trunk/src/opengl/qgl_mac.mm
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) … … 698 698 NSView *view = qt_mac_nativeview_for(w); 699 699 700 // ideally we would use QWidget::isVisible(), but we get "invalid drawable" errors 701 if (![(NSWindow *)qt_mac_window_for(w) isVisible]) 702 return; 700 // Trying to attach the GL context to the NSView will fail with 701 // "invalid drawable" if done too soon, but we have to make sure 702 // the connection is made before the first paint event. Using 703 // the NSView do to this check fails as the NSView is visible 704 // before it's safe to connect, and using the NSWindow fails as 705 // the NSWindow will become visible after the first paint event. 706 // This leaves us with the QWidget, who's visible state seems 707 // to match the point in time when it's safe to connect. 708 if (!w || !w->isVisible()) 709 return; // Not safe to attach GL context to view yet 710 703 711 if ([static_cast<NSOpenGLContext *>(d->cx) view] != view && ![view isHidden]) 704 712 [static_cast<NSOpenGLContext *>(d->cx) setView:view]; … … 805 813 { 806 814 CFBundleRef bundle = 0; 815 CFStringRef urlString = QCFString::toCFStringRef(QLatin1String("/System/Library/Frameworks/OpenGL.framework")); 807 816 QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, 808 QCFString::toCFStringRef(QLatin1String("/System/Library/Frameworks/OpenGL.framework")), kCFURLPOSIXPathStyle, false);817 urlString, kCFURLPOSIXPathStyle, false); 809 818 if (url) 810 819 bundle = CFBundleCreate(kCFAllocatorDefault, url); 820 CFRelease(urlString); 811 821 return bundle; 812 822 } … … 814 824 void *QGLContext::getProcAddress(const QString &proc) const 815 825 { 816 return CFBundleGetFunctionPointerForName(QCFType<CFBundleRef>(qt_getOpenGLBundle()), 817 QCFString(proc)); 826 CFStringRef procName = QCFString(proc).toCFStringRef(proc); 827 void *result = CFBundleGetFunctionPointerForName(QCFType<CFBundleRef>(qt_getOpenGLBundle()), 828 procName); 829 CFRelease(procName); 830 return result; 818 831 } 819 832 #ifndef QT_MAC_USE_COCOA -
trunk/src/opengl/qgl_p.h
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) … … 65 65 #include "qglpaintdevice_p.h" 66 66 67 #ifndef QT_OPENGL_ES_1_CL 68 #define q_vertexType float 69 #define q_vertexTypeEnum GL_FLOAT 70 #define f2vt(f) (f) 71 #define vt2f(x) (x) 72 #define i2vt(i) (float(i)) 73 #else 74 #define FLOAT2X(f) (int( (f) * (65536))) 75 #define X2FLOAT(x) (float(x) / 65536.0f) 76 #define f2vt(f) FLOAT2X(f) 77 #define i2vt(i) ((i)*65536) 78 #define vt2f(x) X2FLOAT(x) 79 #define q_vertexType GLfixed 80 #define q_vertexTypeEnum GL_FIXED 81 #endif //QT_OPENGL_ES_1_CL 82 83 #if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) 84 QT_BEGIN_INCLUDE_NAMESPACE 85 86 #if defined(QT_OPENGL_ES_2) 87 # include <GLES2/gl2.h> 88 #endif 89 90 #if defined(QT_GLES_EGL) 91 # include <GLES/egl.h> 92 #else 93 # include <EGL/egl.h> 94 #endif 95 96 QT_END_INCLUDE_NAMESPACE 67 #ifndef QT_NO_EGL 68 #include <QtGui/private/qegl_p.h> 97 69 #endif 98 70 … … 115 87 # ifdef old_qDebug 116 88 # undef qDebug 117 # define qDebug QT_ QDEBUG_MACRO89 # define qDebug QT_NO_QDEBUG_MACRO 118 90 # undef old_qDebug 119 91 # endif … … 125 97 #endif 126 98 127 #if defined(QT_OPENGL_ES)99 #ifndef QT_NO_EGL 128 100 class QEglContext; 129 101 #endif … … 139 111 : ref(1) 140 112 { 141 opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering | QGL::StencilBuffer; 113 opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering 114 | QGL::StencilBuffer | QGL::DeprecatedFunctions; 142 115 pln = 0; 143 116 depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1; 144 117 numSamples = -1; 145 118 swapInterval = -1; 119 majorVersion = 1; 120 minorVersion = 0; 121 profile = QGLFormat::NoProfile; 146 122 } 147 123 QGLFormatPrivate(const QGLFormatPrivate *other) … … 157 133 alphaSize(other->alphaSize), 158 134 numSamples(other->numSamples), 159 swapInterval(other->swapInterval) 135 swapInterval(other->swapInterval), 136 majorVersion(other->majorVersion), 137 minorVersion(other->minorVersion), 138 profile(other->profile) 160 139 { 161 140 } … … 172 151 int numSamples; 173 152 int swapInterval; 153 int majorVersion; 154 int minorVersion; 155 QGLFormat::OpenGLContextProfile profile; 174 156 }; 175 157 … … 183 165 , wsurf(0) 184 166 #endif 185 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) 167 #if defined(Q_WS_X11) && !defined(QT_NO_EGL) 168 , eglSurfaceWindowId(0) 169 #endif 170 #if defined(Q_OS_SYMBIAN) 186 171 , eglSurfaceWindowId(0) 187 172 #endif … … 196 181 bool renderCxPm(QPixmap *pixmap); 197 182 void cleanupColormaps(); 183 void aboutToDestroy() { 184 if (glcx) 185 glcx->reset(); 186 } 198 187 199 188 QGLContext *glcx; … … 213 202 #elif defined(Q_WS_X11) 214 203 QGLOverlayWidget *olw; 215 #if defined(QT_OPENGL_ES)216 void recreateEglSurface( bool force);204 #ifndef QT_NO_EGL 205 void recreateEglSurface(); 217 206 WId eglSurfaceWindowId; 218 207 #endif … … 223 212 QWSGLWindowSurface *wsurf; 224 213 #endif 214 #ifdef Q_OS_SYMBIAN 215 void recreateEglSurface(); 216 WId eglSurfaceWindowId; 217 #endif 225 218 }; 226 219 … … 249 242 static void removeShare(const QGLContext *context); 250 243 private: 251 QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { }244 QGLContextGroup(const QGLContext *context); 252 245 253 246 QGLExtensionFuncs m_extensionFuncs; … … 292 285 ETC1TextureCompression = 0x00010000, 293 286 PVRTCTextureCompression = 0x00020000, 294 FragmentShader = 0x00040000 287 FragmentShader = 0x00040000, 288 ElementIndexUint = 0x00080000, 289 Depth24 = 0x00100000 295 290 }; 296 291 Q_DECLARE_FLAGS(Extensions, Extension) 297 292 298 293 static Extensions glExtensions(); 299 300 private:301 294 static Extensions currentContextExtensions(); 302 295 }; … … 325 318 326 319 class QGLTexture; 320 class QGLTextureDestroyer; 327 321 328 322 // This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's … … 334 328 Q_DECLARE_PUBLIC(QGLContext) 335 329 public: 336 explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {group = new QGLContextGroup(context);}330 explicit QGLContextPrivate(QGLContext *context); 337 331 ~QGLContextPrivate(); 338 332 QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, … … 351 345 void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true); 352 346 void syncGlState(); // Makes sure the GL context's state is what we think it is 347 void swapRegion(const QRegion ®ion); 348 349 #if defined(Q_WS_WIN) 350 void updateFormatVersion(); 351 #endif 353 352 354 353 #if defined(Q_WS_WIN) … … 361 360 HDC hbitmap_hdc; 362 361 #endif 363 #if defined(QT_OPENGL_ES) 362 #ifndef QT_NO_EGL 363 uint ownsEglContext : 1; 364 364 QEglContext *eglContext; 365 365 EGLSurface eglSurface; 366 366 void destroyEglSurfaceForDevice(); 367 EGLSurface eglSurfaceForDevice() const; 367 368 #elif defined(Q_WS_X11) || defined(Q_WS_MAC) 368 369 void* cx; … … 376 377 int screen; 377 378 QHash<QPixmapData*, QPixmap> boundPixmaps; 378 QGLTexture *bindTextureFromNativePixmap(QPixmap Data*, const qint64 key,379 QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key, 379 380 QGLContext::BindOptions options); 380 381 static void destroyGlSurfaceForPixmap(QPixmapData*); … … 397 398 uint version_flags_cached : 1; 398 399 uint extension_flags_cached : 1; 400 401 // workarounds for driver/hw bugs on different platforms 402 uint workaround_needsFullClearOnEveryFrame : 1; 403 uint workaround_brokenFBOReadBack : 1; 404 uint workaround_brokenTexSubImage : 1; 405 uint workaroundsCached : 1; 406 407 uint workaround_brokenTextureFromPixmap : 1; 408 uint workaround_brokenTextureFromPixmap_init : 1; 409 399 410 QPaintDevice *paintDevice; 400 411 QColor transpColor; … … 409 420 GLuint default_fbo; 410 421 QPaintEngine *active_engine; 422 QGLTextureDestroyer *texture_destroyer; 411 423 412 424 bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT]; … … 418 430 #endif 419 431 420 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) 432 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) 421 433 static QGLExtensionFuncs qt_extensionFuncs; 422 static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *) { return qt_extensionFuncs; }434 static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *); 423 435 #endif 424 436 425 437 static void setCurrentContext(QGLContext *context); 426 };427 428 // ### make QGLContext a QObject in 5.0 and remove the proxy stuff429 class Q_OPENGL_EXPORT QGLSignalProxy : public QObject430 {431 Q_OBJECT432 public:433 QGLSignalProxy() : QObject() {}434 void emitAboutToDestroyContext(const QGLContext *context) {435 emit aboutToDestroyContext(context);436 }437 static QGLSignalProxy *instance();438 Q_SIGNALS:439 void aboutToDestroyContext(const QGLContext *context);440 438 }; 441 439 … … 482 480 }; 483 481 482 class QGLTextureDestroyer : public QObject 483 { 484 Q_OBJECT 485 public: 486 QGLTextureDestroyer() : QObject() { 487 qRegisterMetaType<GLuint>("GLuint"); 488 connect(this, SIGNAL(freeTexture(QGLContext *, QPixmapData *, GLuint)), 489 this, SLOT(freeTexture_slot(QGLContext *, QPixmapData *, GLuint))); 490 } 491 void emitFreeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id) { 492 emit freeTexture(context, boundPixmap, id); 493 } 494 495 Q_SIGNALS: 496 void freeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id); 497 498 private slots: 499 void freeTexture_slot(QGLContext *context, QPixmapData *boundPixmap, GLuint id) { 500 #if defined(Q_WS_X11) 501 if (boundPixmap) { 502 QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); 503 context->makeCurrent(); 504 // Although glXReleaseTexImage is a glX call, it must be called while there 505 // is a current context - the context the pixmap was bound to a texture in. 506 // Otherwise the release doesn't do anything and you get BadDrawable errors 507 // when you come to delete the context. 508 QGLContextPrivate::unbindPixmapFromTexture(boundPixmap); 509 glDeleteTextures(1, &id); 510 if (oldContext) 511 oldContext->makeCurrent(); 512 return; 513 } 514 #endif 515 QGLShareContextScope scope(context); 516 glDeleteTextures(1, &id); 517 } 518 }; 519 520 // ### make QGLContext a QObject in 5.0 and remove the proxy stuff 521 class Q_OPENGL_EXPORT QGLSignalProxy : public QObject 522 { 523 Q_OBJECT 524 public: 525 void emitAboutToDestroyContext(const QGLContext *context) { 526 emit aboutToDestroyContext(context); 527 } 528 static QGLSignalProxy *instance(); 529 Q_SIGNALS: 530 void aboutToDestroyContext(const QGLContext *context); 531 }; 532 484 533 class QGLTexture { 485 534 public: … … 498 547 if (options & QGLContext::MemoryManagedBindOption) { 499 548 Q_ASSERT(context); 500 QGLShareContextScope scope(context); 501 #if defined(Q_WS_X11) 502 // Although glXReleaseTexImage is a glX call, it must be called while there 503 // is a current context - the context the pixmap was bound to a texture in. 504 // Otherwise the release doesn't do anything and you get BadDrawable errors 505 // when you come to delete the context. 506 if (boundPixmap) 507 QGLContextPrivate::unbindPixmapFromTexture(boundPixmap); 508 #endif 509 glDeleteTextures(1, &id); 549 #if !defined(Q_WS_X11) 550 QPixmapData *boundPixmap = 0; 551 #endif 552 context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id); 510 553 } 511 554 } … … 531 574 }; 532 575 576 struct QGLTextureCacheKey { 577 qint64 key; 578 QGLContextGroup *group; 579 }; 580 581 inline bool operator==(const QGLTextureCacheKey &a, const QGLTextureCacheKey &b) 582 { 583 return a.key == b.key && a.group == b.group; 584 } 585 586 inline uint qHash(const QGLTextureCacheKey &key) 587 { 588 return qHash(key.key) ^ qHash(key.group); 589 } 590 591 533 592 class Q_AUTOTEST_EXPORT QGLTextureCache { 534 593 public: … … 537 596 538 597 void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost); 539 void remove(quint64 key) { m_cache.remove(key); } 598 void remove(qint64 key); 599 inline int size(); 600 inline void setMaxCost(int newMax); 601 inline int maxCost(); 602 inline QGLTexture* getTexture(QGLContext *ctx, qint64 key); 603 540 604 bool remove(QGLContext *ctx, GLuint textureId); 541 605 void removeContextTextures(QGLContext *ctx); 542 int size() { return m_cache.size(); }543 void setMaxCost(int newMax) { m_cache.setMaxCost(newMax); }544 int maxCost() {return m_cache.maxCost(); }545 QGLTexture* getTexture(quint64 key) { return m_cache.object(key); }546 547 606 static QGLTextureCache *instance(); 548 static void deleteIfEmpty();549 607 static void cleanupTexturesForCacheKey(qint64 cacheKey); 550 608 static void cleanupTexturesForPixampData(QPixmapData* pixmap); … … 552 610 553 611 private: 554 QCache<qint64, QGLTexture> m_cache; 555 }; 556 612 QCache<QGLTextureCacheKey, QGLTexture> m_cache; 613 QReadWriteLock m_lock; 614 }; 615 616 int QGLTextureCache::size() { 617 QReadLocker locker(&m_lock); 618 return m_cache.size(); 619 } 620 621 void QGLTextureCache::setMaxCost(int newMax) 622 { 623 QWriteLocker locker(&m_lock); 624 m_cache.setMaxCost(newMax); 625 } 626 627 int QGLTextureCache::maxCost() 628 { 629 QReadLocker locker(&m_lock); 630 return m_cache.maxCost(); 631 } 632 633 QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key) 634 { 635 QReadLocker locker(&m_lock); 636 const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; 637 return m_cache.object(cacheKey); 638 } 557 639 558 640 extern Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine(); -
trunk/src/opengl/qgl_qws.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) … … 118 118 else 119 119 return false; 120 }121 122 void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)123 {124 // Find the QGLScreen for this paint device.125 QGLScreen *glScreen = glScreenForDevice(device);126 if (!glScreen) {127 qWarning("QGLContext::chooseContext(): The screen is not a QGLScreen");128 return;129 }130 int devType = device->devType();131 if (devType == QInternal::Image)132 props.setPixelFormat(static_cast<QImage *>(device)->format());133 else134 props.setPixelFormat(glScreen->pixelFormat());135 120 } 136 121 … … 198 183 // Get the display and initialize it. 199 184 d->eglContext = new QEglContext(); 185 d->ownsEglContext = true; 200 186 d->eglContext->setApi(QEgl::OpenGL); 201 187 202 188 // Construct the configuration we need for this surface. 203 189 QEglProperties configProps; 204 qt_egl_add_platform_config(configProps, device()); 205 qt_egl_set_format(configProps, devType, d->glFormat); 190 qt_eglproperties_set_glformat(configProps, d->glFormat); 191 configProps.setDeviceType(devType); 192 configProps.setPaintDeviceFormat(device()); 206 193 configProps.setRenderableType(QEgl::OpenGL); 207 194 … … 215 202 216 203 // Inform the higher layers about the actual format properties. 217 qt_ egl_update_format(*(d->eglContext), d->glFormat);204 qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); 218 205 219 206 // Create a new context for the configuration. -
trunk/src/opengl/qgl_win.cpp
r651 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) … … 123 123 #endif 124 124 125 #ifndef WGL_ARB_create_context 126 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 127 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 128 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 129 #define WGL_CONTEXT_FLAGS_ARB 0x2094 130 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 131 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 132 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 133 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001 134 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002 135 // Error codes returned by GetLastError(). 136 #define ERROR_INVALID_VERSION_ARB 0x2095 137 #define ERROR_INVALID_PROFILE_ARB 0x2096 138 #endif 139 140 #ifndef GL_VERSION_3_2 141 #define GL_CONTEXT_PROFILE_MASK 0x9126 142 #define GL_MAJOR_VERSION 0x821B 143 #define GL_MINOR_VERSION 0x821C 144 #define GL_NUM_EXTENSIONS 0x821D 145 #define GL_CONTEXT_FLAGS 0x821E 146 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 147 #endif 148 125 149 QT_BEGIN_NAMESPACE 126 150 … … 683 707 } 684 708 709 static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext) 710 { 711 d->rc = 0; 712 713 typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *); 714 PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB = 715 (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB"); 716 if (wglCreateContextAttribsARB) { 717 int attributes[11]; 718 int attribIndex = 0; 719 const int major = d->reqFormat.majorVersion(); 720 const int minor = d->reqFormat.minorVersion(); 721 attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB; 722 attributes[attribIndex++] = major; 723 attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB; 724 attributes[attribIndex++] = minor; 725 726 if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) { 727 attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB; 728 attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; 729 } 730 731 if ((major == 3 && minor >= 2) || major > 3) { 732 switch (d->reqFormat.profile()) { 733 case QGLFormat::NoProfile: 734 break; 735 case QGLFormat::CoreProfile: 736 attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB; 737 attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; 738 break; 739 case QGLFormat::CompatibilityProfile: 740 attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB; 741 attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 742 break; 743 default: 744 qWarning("QGLContext::chooseContext(): Context profile not supported."); 745 return false; 746 } 747 } 748 749 if (d->reqFormat.plane() != 0) { 750 attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB; 751 attributes[attribIndex++] = d->reqFormat.plane(); 752 } 753 754 attributes[attribIndex++] = 0; // Terminate list. 755 d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid 756 ? shareContext->rc : 0, attributes); 757 if (d->rc) { 758 if (shareContext) 759 shareContext->sharing = d->sharing = true; 760 return true; 761 } 762 } 763 764 d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane()); 765 if (d->rc && shareContext && shareContext->valid) 766 shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc); 767 return d->rc != 0; 768 } 769 770 void QGLContextPrivate::updateFormatVersion() 771 { 772 const GLubyte *s = glGetString(GL_VERSION); 773 774 if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) { 775 if (!s) 776 qWarning("QGLContext::chooseContext(): OpenGL version string is null."); 777 else 778 qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format."); 779 glFormat.setVersion(0, 0); 780 glFormat.setProfile(QGLFormat::NoProfile); 781 glFormat.setOption(QGL::DeprecatedFunctions); 782 return; 783 } 784 785 int major = s[0] - '0'; 786 int minor = s[2] - '0'; 787 glFormat.setVersion(major, minor); 788 789 if (major < 3) { 790 glFormat.setProfile(QGLFormat::NoProfile); 791 glFormat.setOption(QGL::DeprecatedFunctions); 792 } else { 793 GLint value = 0; 794 if (major > 3 || minor >= 2) 795 glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); 796 797 switch (value) { 798 case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: 799 glFormat.setProfile(QGLFormat::CoreProfile); 800 break; 801 case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: 802 glFormat.setProfile(QGLFormat::CompatibilityProfile); 803 break; 804 default: 805 glFormat.setProfile(QGLFormat::NoProfile); 806 break; 807 } 808 809 glGetIntegerv(GL_CONTEXT_FLAGS, &value); 810 if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) 811 glFormat.setOption(QGL::NoDeprecatedFunctions); 812 else 813 glFormat.setOption(QGL::DeprecatedFunctions); 814 } 815 } 816 685 817 bool QGLContext::chooseContext(const QGLContext* shareContext) 686 818 { 819 QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0; 820 687 821 Q_D(QGLContext); 688 822 // workaround for matrox driver: … … 742 876 } 743 877 744 d->rc = wglCreateLayerContext(myDc, d->glFormat.plane()); 745 if (!d->rc) { 878 if (!qgl_create_context(myDc, d, share)) { 746 879 qwglError("QGLContext::chooseContext()", "CreateLayerContext"); 747 880 result = false; … … 793 926 d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved); 794 927 } 795 796 if (shareContext && shareContext->isValid()) { 797 QGLContext *share = const_cast<QGLContext *>(shareContext); 798 d->sharing = (wglShareLists(shareContext->d_func()->rc, d->rc) != 0); 799 share->d_func()->sharing = d->sharing; 800 } 801 802 goto end; 803 } 804 { 928 } else { 805 929 PIXELFORMATDESCRIPTOR pfd; 806 930 PIXELFORMATDESCRIPTOR realPfd; … … 841 965 } 842 966 843 if (! (d->rc = wglCreateLayerContext(myDc, 0))) {967 if (!qgl_create_context(myDc, d, share)) { 844 968 qwglError("QGLContext::chooseContext()", "wglCreateContext"); 845 969 result = false; 846 970 goto end; 847 }848 849 if (shareContext && shareContext->isValid()) {850 d->sharing = (wglShareLists(shareContext->d_func()->rc, d->rc) != 0);851 const_cast<QGLContext *>(shareContext)->d_func()->sharing = d->sharing;852 971 } 853 972 … … 866 985 // vblanking 867 986 wglMakeCurrent(myDc, d->rc); 987 if (d->rc) 988 d->updateFormatVersion(); 989 868 990 typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval); 869 991 typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void); … … 921 1043 iAttributes[i++] = TRUE; 922 1044 iAttributes[i++] = WGL_COLOR_BITS_ARB; 923 iAttributes[i++] = 32;1045 iAttributes[i++] = 24; 924 1046 iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; 925 1047 iAttributes[i++] = d->glFormat.doubleBuffer(); … … 1159 1281 { 1160 1282 Q_D(QGLContext); 1161 if (d->rc == wglGetCurrentContext() || !d->valid) 1283 if (d->rc == wglGetCurrentContext() || !d->valid) // already current 1162 1284 return; 1285 1163 1286 if (d->win) { 1164 1287 d->dc = GetDC(d->win); -
trunk/src/opengl/qgl_wince.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) … … 55 55 #include <windows.h> 56 56 57 #include <private/qegl_p.h> 57 #include <private/qeglproperties_p.h> 58 #include <private/qeglcontext_p.h> 58 59 #include <private/qgl_egl_p.h> 59 #include <private/qgl_cl_p.h>60 60 61 61 … … 121 121 QGLFormat Win32/WGL-specific code 122 122 *****************************************************************************/ 123 124 void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)125 {126 int devType = device->devType();127 if (devType == QInternal::Image)128 props.setPixelFormat(static_cast<QImage *>(device)->format());129 else130 props.setPixelFormat(QImage::Format_RGB16);131 }132 133 123 134 124 static bool opengl32dll = false; … … 155 145 // Get the display and initialize it. 156 146 d->eglContext = new QEglContext(); 147 d->ownsEglContext = true; 157 148 d->eglContext->setApi(QEgl::OpenGL); 158 149 159 150 // Construct the configuration we need for this surface. 160 151 QEglProperties configProps; 161 qt_egl_add_platform_config(configProps, device()); 162 qt_egl_set_format(configProps, devType, d->glFormat); 152 qt_eglproperties_set_glformat(configProps, d->glFormat); 153 configProps.setDeviceType(devType); 154 configProps.setPaintDeviceFormat(device()); 163 155 configProps.setRenderableType(QEgl::OpenGL); 164 156 … … 172 164 173 165 // Inform the higher layers about the actual format properties. 174 qt_ egl_update_format(*(d->eglContext), d->glFormat);166 qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); 175 167 176 168 // Create a new context for the configuration. -
trunk/src/opengl/qgl_x11.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) … … 55 55 #include <private/qpixmap_x11_p.h> 56 56 #include <private/qimagepixmapcleanuphooks_p.h> 57 #include <private/qunicodetables_p.h> 57 58 #ifdef Q_OS_HPUX 58 59 // for GLXPBuffer … … 114 115 #define GLX_TEXTURE_RECTANGLE_EXT 0x20DD 115 116 #define GLX_FRONT_LEFT_EXT 0x20DE 117 #endif 118 119 #ifndef GLX_ARB_create_context 120 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 121 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 122 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 123 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 124 #define GLX_CONTEXT_FLAGS_ARB 0x2094 125 #endif 126 127 #ifndef GLX_ARB_create_context_profile 128 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 129 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 130 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 116 131 #endif 117 132 … … 400 415 find_trans_colors(); 401 416 return trans_colors.size() > 0; 417 } 418 419 static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice, 420 int bufDepth, bool onlyFBConfig = false) 421 { 422 int i = 0; 423 spec[i++] = GLX_LEVEL; 424 spec[i++] = f.plane(); 425 const QX11Info *xinfo = qt_x11Info(paintDevice); 426 bool useFBConfig = onlyFBConfig; 427 428 #if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) 429 /* 430 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 431 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 432 */ 433 QWidget* widget = 0; 434 if (paintDevice->devType() == QInternal::Widget) 435 widget = static_cast<QWidget*>(paintDevice); 436 437 // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual 438 if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) 439 useFBConfig = true; 440 #endif 441 442 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) 443 static bool useTranspExt = false; 444 static bool useTranspExtChecked = false; 445 if (f.plane() && !useTranspExtChecked && paintDevice) { 446 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 447 useTranspExt = extensions.match("GLX_EXT_visual_info"); 448 //# (A bit simplistic; that could theoretically be a substring) 449 if (useTranspExt) { 450 QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); 451 useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround 452 if (useTranspExt) { 453 // bug workaround - some systems (eg. FireGL) refuses to return an overlay 454 // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if 455 // the implementation supports transparent overlays 456 int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, 457 f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, 458 XNone }; 459 XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); 460 if (!vinf) { 461 useTranspExt = false; 462 } 463 } 464 } 465 466 useTranspExtChecked = true; 467 } 468 if (f.plane() && useTranspExt && !useFBConfig) { 469 // Required to avoid non-transparent overlay visual(!) on some systems 470 spec[i++] = GLX_TRANSPARENT_TYPE_EXT; 471 spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 472 } 473 #endif 474 475 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 476 // GLX_RENDER_TYPE is only in glx >=1.3 477 if (useFBConfig) { 478 spec[i++] = GLX_RENDER_TYPE; 479 spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; 480 } 481 #endif 482 483 if (f.doubleBuffer()) 484 spec[i++] = GLX_DOUBLEBUFFER; 485 if (useFBConfig) 486 spec[i++] = True; 487 if (f.depth()) { 488 spec[i++] = GLX_DEPTH_SIZE; 489 spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); 490 } 491 if (f.stereo()) { 492 spec[i++] = GLX_STEREO; 493 if (useFBConfig) 494 spec[i++] = True; 495 } 496 if (f.stencil()) { 497 spec[i++] = GLX_STENCIL_SIZE; 498 spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); 499 } 500 if (f.rgba()) { 501 if (!useFBConfig) 502 spec[i++] = GLX_RGBA; 503 spec[i++] = GLX_RED_SIZE; 504 spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); 505 spec[i++] = GLX_GREEN_SIZE; 506 spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); 507 spec[i++] = GLX_BLUE_SIZE; 508 spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); 509 if (f.alpha()) { 510 spec[i++] = GLX_ALPHA_SIZE; 511 spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); 512 } 513 if (f.accum()) { 514 spec[i++] = GLX_ACCUM_RED_SIZE; 515 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 516 spec[i++] = GLX_ACCUM_GREEN_SIZE; 517 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 518 spec[i++] = GLX_ACCUM_BLUE_SIZE; 519 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 520 if (f.alpha()) { 521 spec[i++] = GLX_ACCUM_ALPHA_SIZE; 522 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 523 } 524 } 525 } else { 526 spec[i++] = GLX_BUFFER_SIZE; 527 spec[i++] = bufDepth; 528 } 529 530 if (f.sampleBuffers()) { 531 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 532 spec[i++] = 1; 533 spec[i++] = GLX_SAMPLES_ARB; 534 spec[i++] = f.samples() == -1 ? 4 : f.samples(); 535 } 536 537 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 538 if (useFBConfig) { 539 spec[i++] = GLX_DRAWABLE_TYPE; 540 switch(paintDevice->devType()) { 541 case QInternal::Pixmap: 542 spec[i++] = GLX_PIXMAP_BIT; 543 break; 544 case QInternal::Pbuffer: 545 spec[i++] = GLX_PBUFFER_BIT; 546 break; 547 default: 548 qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType()); 549 // Fall-through & assume it's a window 550 case QInternal::Widget: 551 spec[i++] = GLX_WINDOW_BIT; 552 break; 553 }; 554 } 555 #endif 556 557 spec[i] = XNone; 558 return useFBConfig; 402 559 } 403 560 … … 494 651 } 495 652 653 const int major = d->reqFormat.majorVersion(); 654 const int minor = d->reqFormat.minorVersion(); 655 const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile 656 ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 657 : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; 658 496 659 d->cx = 0; 497 if (shareContext) { 660 661 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 662 /* 663 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 664 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 665 */ 666 if ((major == 3 && minor >= 2) || major > 3) { 667 QGLTemporaryContext *tmpContext = 0; 668 if (!QGLContext::currentContext()) 669 tmpContext = new QGLTemporaryContext; 670 671 int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, 672 GLX_CONTEXT_MINOR_VERSION_ARB, minor, 673 GLX_CONTEXT_PROFILE_MASK_ARB, profile, 674 0 }; 675 676 typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) 677 (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); 678 679 680 Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = 681 (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); 682 683 if (glXCreateContextAttribs) { 684 int spec[45]; 685 glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res); 686 buildSpec(spec, format(), d->paintDevice, res, true); 687 688 GLXFBConfig *configs; 689 int configCount = 0; 690 configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount); 691 692 if (configs && configCount > 0) { 693 d->cx = glXCreateContextAttribs(disp, configs[0], 694 shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes); 695 if (!d->cx && shareContext) { 696 shareContext = 0; 697 d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes); 698 } 699 d->screen = ((XVisualInfo*)d->vi)->screen; 700 } 701 XFree(configs); 702 } else { 703 qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor); 704 } 705 706 if (tmpContext) 707 delete tmpContext; 708 } 709 #else 710 Q_UNUSED(major); 711 Q_UNUSED(minor); 712 Q_UNUSED(profile); 713 #endif 714 715 if (!d->cx && shareContext) { 498 716 d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, 499 717 (GLXContext)shareContext->d_func()->cx, direct); 500 718 d->screen = ((XVisualInfo*)d->vi)->screen; 501 if (d->cx) {502 QGLContext *share = const_cast<QGLContext *>(shareContext);503 d->sharing = true;504 share->d_func()->sharing = true;505 }506 719 } 507 720 if (!d->cx) { 508 721 d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); 509 722 d->screen = ((XVisualInfo*)d->vi)->screen; 510 } 723 shareContext = 0; 724 } 725 726 if (shareContext && d->cx) { 727 QGLContext *share = const_cast<QGLContext *>(shareContext); 728 d->sharing = true; 729 share->d_func()->sharing = true; 730 } 731 511 732 if (!d->cx) 512 733 return false; … … 607 828 Q_D(QGLContext); 608 829 int spec[45]; 609 int i = 0;610 spec[i++] = GLX_LEVEL;611 spec[i++] = f.plane();612 830 const QX11Info *xinfo = qt_x11Info(d->paintDevice); 613 bool useFBConfig = false; 614 615 #if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) 616 /* 617 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 618 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 619 */ 620 QWidget* widget = 0; 621 if (d->paintDevice->devType() == QInternal::Widget) 622 widget = static_cast<QWidget*>(d->paintDevice); 623 624 // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual 625 if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) 626 useFBConfig = true; 627 #endif 628 629 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) 630 static bool useTranspExt = false; 631 static bool useTranspExtChecked = false; 632 if (f.plane() && !useTranspExtChecked && d->paintDevice) { 633 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 634 useTranspExt = extensions.match("GLX_EXT_visual_info"); 635 //# (A bit simplistic; that could theoretically be a substring) 636 if (useTranspExt) { 637 QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); 638 useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround 639 if (useTranspExt) { 640 // bug workaround - some systems (eg. FireGL) refuses to return an overlay 641 // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if 642 // the implementation supports transparent overlays 643 int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, 644 f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, 645 XNone }; 646 XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); 647 if (!vinf) { 648 useTranspExt = false; 649 } 650 } 651 } 652 653 useTranspExtChecked = true; 654 } 655 if (f.plane() && useTranspExt && !useFBConfig) { 656 // Required to avoid non-transparent overlay visual(!) on some systems 657 spec[i++] = GLX_TRANSPARENT_TYPE_EXT; 658 spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 659 } 660 #endif 661 662 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 663 // GLX_RENDER_TYPE is only in glx >=1.3 664 if (useFBConfig) { 665 spec[i++] = GLX_RENDER_TYPE; 666 spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; 667 } 668 #endif 669 670 if (f.doubleBuffer()) 671 spec[i++] = GLX_DOUBLEBUFFER; 672 if (useFBConfig) 673 spec[i++] = True; 674 if (f.depth()) { 675 spec[i++] = GLX_DEPTH_SIZE; 676 spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); 677 } 678 if (f.stereo()) { 679 spec[i++] = GLX_STEREO; 680 if (useFBConfig) 681 spec[i++] = True; 682 } 683 if (f.stencil()) { 684 spec[i++] = GLX_STENCIL_SIZE; 685 spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); 686 } 687 if (f.rgba()) { 688 if (!useFBConfig) 689 spec[i++] = GLX_RGBA; 690 spec[i++] = GLX_RED_SIZE; 691 spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); 692 spec[i++] = GLX_GREEN_SIZE; 693 spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); 694 spec[i++] = GLX_BLUE_SIZE; 695 spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); 696 if (f.alpha()) { 697 spec[i++] = GLX_ALPHA_SIZE; 698 spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); 699 } 700 if (f.accum()) { 701 spec[i++] = GLX_ACCUM_RED_SIZE; 702 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 703 spec[i++] = GLX_ACCUM_GREEN_SIZE; 704 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 705 spec[i++] = GLX_ACCUM_BLUE_SIZE; 706 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 707 if (f.alpha()) { 708 spec[i++] = GLX_ACCUM_ALPHA_SIZE; 709 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 710 } 711 } 712 } else { 713 spec[i++] = GLX_BUFFER_SIZE; 714 spec[i++] = bufDepth; 715 } 716 717 if (f.sampleBuffers()) { 718 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 719 spec[i++] = 1; 720 spec[i++] = GLX_SAMPLES_ARB; 721 spec[i++] = f.samples() == -1 ? 4 : f.samples(); 722 } 723 724 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 725 if (useFBConfig) { 726 spec[i++] = GLX_DRAWABLE_TYPE; 727 switch(d->paintDevice->devType()) { 728 case QInternal::Pixmap: 729 spec[i++] = GLX_PIXMAP_BIT; 730 break; 731 case QInternal::Pbuffer: 732 spec[i++] = GLX_PBUFFER_BIT; 733 break; 734 default: 735 qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType()); 736 // Fall-through & assume it's a window 737 case QInternal::Widget: 738 spec[i++] = GLX_WINDOW_BIT; 739 break; 740 }; 741 } 742 #endif 743 744 spec[i] = XNone; 745 831 bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false); 746 832 747 833 XVisualInfo* chosenVisualInfo = 0; … … 756 842 break; // fallback to trying glXChooseVisual 757 843 758 for (i = 0; i < configCount; ++i) {844 for (int i = 0; i < configCount; ++i) { 759 845 XVisualInfo* vi; 760 846 vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); … … 844 930 ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx); 845 931 } else if (d->paintDevice->devType() == QInternal::Widget) { 846 ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)-> winId(), (GLXContext)d->cx);932 ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx); 847 933 } 848 934 if (!ok) … … 1672 1758 1673 1759 1674 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap Data *pmd, const qint64 key,1760 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, 1675 1761 QGLContext::BindOptions options) 1676 1762 { … … 1678 1764 return 0; 1679 1765 #else 1766 1767 // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap 1768 int majorVersion = 0; 1769 int minorVersion = 0; 1770 glXQueryVersion(X11->display, &majorVersion, &minorVersion); 1771 if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3)) 1772 return 0; 1773 1680 1774 Q_Q(QGLContext); 1681 1775 1682 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 1776 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); 1777 Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); 1778 1779 // We can't use TFP if the pixmap has a separate X11 mask 1780 if (pixmapData->x11_mask) 1781 return 0; 1683 1782 1684 1783 if (!qt_resolveTextureFromPixmap(paintDevice)) 1685 1784 return 0; 1686 1785 1687 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);1688 1786 const QX11Info &x11Info = pixmapData->xinfo; 1689 1787 … … 1754 1852 return 0; 1755 1853 1756 pixmapData->gl_surface = ( Qt::HANDLE)glxPixmap;1854 pixmapData->gl_surface = (void*)glxPixmap; 1757 1855 1758 1856 // Make sure the cleanup hook gets called so we can delete the glx pixmap … … 1766 1864 1767 1865 glBindTexture(GL_TEXTURE_2D, textureId); 1866 GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST; 1867 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 1868 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 1768 1869 1769 1870 if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted))) -
trunk/src/opengl/qgl_x11egl.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 <private/qt_x11_p.h> 44 44 #include <private/qpixmap_x11_p.h> 45 #include <private/qimagepixmapcleanuphooks_p.h>46 45 #include <private/qgl_p.h> 47 46 #include <private/qpaintengine_opengl_p.h> … … 49 48 #include "qcolormap.h" 50 49 #include <QDebug> 50 #include <QPixmap> 51 51 52 52 53 53 QT_BEGIN_NAMESPACE 54 54 55 56 bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config,57 const QX11Info &x11Info, bool useArgbVisual);58 55 59 56 /* … … 80 77 int screen = 0; 81 78 82 d->display = eglGetDisplay(EGLNativeDisplayType(X11->display)); 83 84 if (!eglInitialize(d->display, NULL, NULL)) { 85 qWarning("QGLTemporaryContext: Unable to initialize EGL display."); 86 return; 87 } 79 d->display = QEgl::display(); 88 80 89 81 EGLConfig config; … … 106 98 XVisualInfo *vi; 107 99 int numVisuals; 108 EGLint id = 0; 109 110 eglGetConfigAttrib(d->display, config, EGL_NATIVE_VISUAL_ID, &id); 111 if (id == 0) { 112 // EGL_NATIVE_VISUAL_ID is optional and might not be supported 113 // on some implementations - we'll have to do it the hard way 114 QX11Info xinfo; 115 qt_egl_setup_x11_visual(visualInfo, d->display, config, xinfo, false); 116 } else { 117 visualInfo.visualid = id; 118 } 100 101 visualInfo.visualid = QEgl::getCompatibleVisualId(config); 119 102 vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); 120 103 if (!vi || numVisuals < 1) { … … 171 154 } 172 155 173 void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)174 {175 if (device->devType() == QInternal::Image)176 props.setPixelFormat(static_cast<QImage *>(device)->format());177 }178 179 156 // Chooses the EGL config and creates the EGL context 180 157 bool QGLContext::chooseContext(const QGLContext* shareContext) … … 187 164 int devType = device()->devType(); 188 165 189 // Get the display and initialize it. 166 QX11PixmapData *x11PixmapData = 0; 167 if (devType == QInternal::Pixmap) { 168 QPixmapData *pmd = static_cast<QPixmap*>(device())->data_ptr().data(); 169 if (pmd->classId() == QPixmapData::X11Class) 170 x11PixmapData = static_cast<QX11PixmapData*>(pmd); 171 else { 172 // TODO: Replace the pixmap's data with a new QX11PixmapData 173 qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend"); 174 return false; 175 } 176 } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { 177 qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType); 178 return false; 179 } 180 181 // Only create the eglContext if we don't already have one: 190 182 if (d->eglContext == 0) { 191 183 d->eglContext = new QEglContext(); 184 d->ownsEglContext = true; 192 185 d->eglContext->setApi(QEgl::OpenGL); 186 187 // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat 188 // has the alpha channel option set: 189 if (devType == QInternal::Widget) { 190 QWidget* widget = static_cast<QWidget*>(device()); 191 if (widget->testAttribute(Qt::WA_TranslucentBackground)) 192 d->glFormat.setAlpha(true); 193 } 193 194 194 195 // Construct the configuration we need for this surface. 195 196 QEglProperties configProps; 196 qt_egl_set_format(configProps, devType, d->glFormat); 197 qt_egl_add_platform_config(configProps, device()); 197 configProps.setDeviceType(devType); 198 198 configProps.setRenderableType(QEgl::OpenGL); 199 200 #if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE 201 if (device()->depth() == 16 && configProps.value(EGL_ALPHA_SIZE) <= 0) { 202 qDebug("Setting EGL_BUFFER_SIZE to 16"); 203 configProps.setValue(EGL_BUFFER_SIZE, 16); 204 configProps.setValue(EGL_ALPHA_SIZE, 0); 205 } 199 qt_eglproperties_set_glformat(configProps, d->glFormat); 200 201 // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed: 202 if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0) 203 configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); 206 204 207 205 if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { … … 210 208 return false; 211 209 } 212 #else 213 QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; 214 if ((device()->depth() == 16) && configProps.value(EGL_ALPHA_SIZE) == 0) { 215 configProps.setValue(EGL_RED_SIZE, 5); 216 configProps.setValue(EGL_GREEN_SIZE, 6); 217 configProps.setValue(EGL_BLUE_SIZE, 5); 218 configProps.setValue(EGL_ALPHA_SIZE, 0); 219 matchType = QEgl::ExactPixelFormat; 220 } 221 222 // Search for a matching configuration, reducing the complexity 223 // each time until we get something that matches. 224 if (!d->eglContext->chooseConfig(configProps, matchType)) { 210 211 // Create a new context for the configuration. 212 QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0; 213 if (!d->eglContext->createContext(eglSharedContext)) { 225 214 delete d->eglContext; 226 215 d->eglContext = 0; 227 216 return false; 228 217 } 229 #endif230 231 // qDebug("QGLContext::chooseContext() - using EGL config %d:", d->eglContext->config());232 // qDebug() << QEglProperties(d->eglContext->config()).toString();233 234 // Create a new context for the configuration.235 if (!d->eglContext->createContext236 (shareContext ? shareContext->d_func()->eglContext : 0)) {237 delete d->eglContext;238 d->eglContext = 0;239 return false;240 }241 218 d->sharing = d->eglContext->isSharing(); 242 219 if (d->sharing && shareContext) 243 220 const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; 244 245 #if defined(EGL_VERSION_1_1) 246 if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) 247 eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); 248 #endif 249 } 250 251 // Inform the higher layers about the actual format properties. 252 qt_egl_update_format(*(d->eglContext), d->glFormat); 221 } 222 223 // Inform the higher layers about the actual format properties 224 qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); 225 226 // Do don't create the EGLSurface for everything. 227 // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface 228 // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface 229 // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface 230 // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf 231 232 if (devType == QInternal::Widget) { 233 if (d->eglSurface != EGL_NO_SURFACE) 234 eglDestroySurface(d->eglContext->display(), d->eglSurface); 235 d->eglSurface = QEgl::createSurface(device(), d->eglContext->config()); 236 XFlush(X11->display); 237 setWindowCreated(true); 238 } 239 240 if (x11PixmapData) { 241 // TODO: Actually check to see if the existing surface can be re-used 242 if (x11PixmapData->gl_surface) 243 eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface); 244 245 x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config()); 246 } 253 247 254 248 return true; … … 282 276 } 283 277 284 //#define QT_DEBUG_X11_VISUAL_SELECTION 1285 286 bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual)287 {288 bool foundVisualIsArgb = useArgbVisual;289 290 #ifdef QT_DEBUG_X11_VISUAL_SELECTION291 qDebug("qt_egl_setup_x11_visual() - useArgbVisual=%d", useArgbVisual);292 #endif293 294 memset(&vi, 0, sizeof(XVisualInfo));295 296 EGLint eglConfigColorSize;297 eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &eglConfigColorSize);298 299 // Check to see if EGL is suggesting an appropriate visual id:300 EGLint nativeVisualId;301 eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId);302 vi.visualid = nativeVisualId;303 304 if (vi.visualid) {305 // EGL has suggested a visual id, so get the rest of the visual info for that id:306 XVisualInfo *chosenVisualInfo;307 int matchingCount = 0;308 chosenVisualInfo = XGetVisualInfo(x11Info.display(), VisualIDMask, &vi, &matchingCount);309 if (chosenVisualInfo) {310 #if !defined(QT_NO_XRENDER)311 if (useArgbVisual) {312 // Check to make sure the visual provided by EGL is ARGB313 XRenderPictFormat *format;314 format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual);315 if (format->type == PictTypeDirect && format->direct.alphaMask) {316 #ifdef QT_DEBUG_X11_VISUAL_SELECTION317 qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);318 #endif319 foundVisualIsArgb = true;320 vi = *chosenVisualInfo;321 }322 else {323 qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB",324 nativeVisualId, (int)config);325 vi.visualid = 0;326 }327 } else328 #endif329 {330 if (eglConfigColorSize == chosenVisualInfo->depth) {331 #ifdef QT_DEBUG_X11_VISUAL_SELECTION332 qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);333 #endif334 vi = *chosenVisualInfo;335 } else336 qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!",337 nativeVisualId, chosenVisualInfo->depth, (int)config, eglConfigColorSize);338 }339 XFree(chosenVisualInfo);340 }341 else {342 qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!",343 nativeVisualId, (int)config);344 vi.visualid = 0;345 }346 }347 348 // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first349 // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo350 351 #if !defined(QT_NO_XRENDER)352 if (vi.visualid == 0 && useArgbVisual) {353 // Try to use XRender to find an ARGB visual we can use354 vi.screen = x11Info.screen();355 vi.depth = 32; //### We might at some point (soon) get ARGB4444356 vi.c_class = TrueColor;357 XVisualInfo *matchingVisuals;358 int matchingCount = 0;359 matchingVisuals = XGetVisualInfo(x11Info.display(),360 VisualScreenMask|VisualDepthMask|VisualClassMask,361 &vi, &matchingCount);362 363 for (int i = 0; i < matchingCount; ++i) {364 XRenderPictFormat *format;365 format = XRenderFindVisualFormat(x11Info.display(), matchingVisuals[i].visual);366 if (format->type == PictTypeDirect && format->direct.alphaMask) {367 vi = matchingVisuals[i];368 foundVisualIsArgb = true;369 #ifdef QT_DEBUG_X11_VISUAL_SELECTION370 qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid);371 #endif372 break;373 }374 }375 XFree(matchingVisuals);376 }377 #endif378 379 if (vi.visualid == 0) {380 EGLint depth;381 eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &depth);382 int err;383 err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi);384 if (err == 0) {385 qWarning("Warning: Can't find an X visual which matches the EGL config(%d)'s depth (%d)!",386 (int)config, depth);387 depth = x11Info.depth();388 err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi);389 if (err == 0) {390 qWarning("Error: Couldn't get any matching X visual!");391 return false;392 } else393 qWarning(" - Falling back to X11 suggested depth (%d)", depth);394 }395 #ifdef QT_DEBUG_X11_VISUAL_SELECTION396 else397 qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);398 #endif399 400 // Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-(401 if (useArgbVisual)402 foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444403 }404 405 #ifdef QT_DEBUG_X11_VISUAL_SELECTION406 qDebug("Visual Info:");407 qDebug(" bits_per_rgb=%d", vi.bits_per_rgb);408 qDebug(" red_mask=0x%x", vi.red_mask);409 qDebug(" green_mask=0x%x", vi.green_mask);410 qDebug(" blue_mask=0x%x", vi.blue_mask);411 qDebug(" colormap_size=%d", vi.colormap_size);412 qDebug(" c_class=%d", vi.c_class);413 qDebug(" depth=%d", vi.depth);414 qDebug(" screen=%d", vi.screen);415 qDebug(" visualid=%d", vi.visualid);416 #endif417 return foundVisualIsArgb;418 }419 420 278 void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) 421 279 { … … 434 292 QGLContext* oldcx = d->glcx; 435 293 d->glcx = context; 436 437 if (parentWidget()) {438 // force creation of delay-created widgets439 parentWidget()->winId();440 if (parentWidget()->x11Info().screen() != x11Info().screen())441 d_func()->xinfo = parentWidget()->d_func()->xinfo;442 }443 444 // If the application has set WA_TranslucentBackground and not explicitly set445 // the alpha buffer size to zero, modify the format so it have an alpha channel446 QGLFormat& fmt = d->glcx->d_func()->glFormat;447 const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground) || fmt.alpha();448 if (tryArgbVisual && fmt.alphaBufferSize() == -1)449 fmt.setAlphaBufferSize(1);450 294 451 295 bool createFailed = false; … … 462 306 } 463 307 464 if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { 465 if (deleteOldContext) 466 delete oldcx; 467 return; 468 } 469 470 bool visible = isVisible(); 471 if (visible) 472 hide(); 473 474 XVisualInfo vi; 475 QEglContext *eglContext = d->glcx->d_func()->eglContext; 476 bool usingArgbVisual = qt_egl_setup_x11_visual(vi, eglContext->display(), eglContext->config(), 477 x11Info(), tryArgbVisual); 478 479 XSetWindowAttributes a; 480 481 Window p = RootWindow(x11Info().display(), x11Info().screen()); 482 if (parentWidget()) 483 p = parentWidget()->winId(); 484 485 QColormap colmap = QColormap::instance(vi.screen); 486 a.background_pixel = colmap.pixel(palette().color(backgroundRole())); 487 a.border_pixel = colmap.pixel(Qt::black); 488 489 unsigned int valueMask = CWBackPixel|CWBorderPixel; 490 if (usingArgbVisual) { 491 a.colormap = XCreateColormap(x11Info().display(), p, vi.visual, AllocNone); 492 valueMask |= CWColormap; 493 } 494 495 Window w = XCreateWindow(x11Info().display(), p, x(), y(), width(), height(), 496 0, vi.depth, InputOutput, vi.visual, valueMask, &a); 497 498 if (deleteOldContext) 499 delete oldcx; 500 oldcx = 0; 501 502 create(w); // Create with the ID of the window we've just created 503 504 505 // Create the EGL surface to draw into. 506 QGLContextPrivate *ctxpriv = d->glcx->d_func(); 507 ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(this); 508 if (ctxpriv->eglSurface == EGL_NO_SURFACE) { 509 delete ctxpriv->eglContext; 510 ctxpriv->eglContext = 0; 511 return; 512 } 513 514 d->eglSurfaceWindowId = w; // Remember the window id we created the surface for 515 516 if (visible) 517 show(); 518 519 XFlush(X11->display); 520 d->glcx->setWindowCreated(true); 308 309 d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for 521 310 } 522 311 … … 527 316 initContext(context, shareWidget); 528 317 529 if (q->isValid() && glcx->format().hasOverlay()) {318 if (q->isValid() && glcx->format().hasOverlay()) { 530 319 //no overlay 531 320 qWarning("QtOpenGL ES doesn't currently support overlays"); … … 546 335 } 547 336 548 // Re-creates the EGL surface if the window ID has changed or if force is true549 void QGLWidgetPrivate::recreateEglSurface( bool force)337 // Re-creates the EGL surface if the window ID has changed or if there isn't a surface 338 void QGLWidgetPrivate::recreateEglSurface() 550 339 { 551 340 Q_Q(QGLWidget); … … 553 342 Window currentId = q->winId(); 554 343 555 if ( force || (currentId != eglSurfaceWindowId) ) { 556 // The window id has changed so we need to re-create the EGL surface 557 QEglContext *ctx = glcx->d_func()->eglContext; 558 EGLSurface surface = glcx->d_func()->eglSurface; 559 if (surface != EGL_NO_SURFACE) 560 ctx->destroySurface(surface); // Will force doneCurrent() if nec. 561 surface = ctx->createSurface(q); 562 if (surface == EGL_NO_SURFACE) 563 qWarning("Error creating EGL window surface: 0x%x", eglGetError()); 564 glcx->d_func()->eglSurface = surface; 565 344 // If the window ID has changed since the surface was created, we need to delete the 345 // old surface before re-creating a new one. Note: This should not be the case as the 346 // surface should be deleted before the old window id. 347 if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) { 348 qWarning("EGL surface for deleted window %x was not destroyed", uint(eglSurfaceWindowId)); 349 glcx->d_func()->destroyEglSurfaceForDevice(); 350 } 351 352 if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) { 353 glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q); 566 354 eglSurfaceWindowId = currentId; 567 355 } 568 356 } 569 357 570 // Selects which configs should be used 571 EGLConfig Q_OPENGL_EXPORT qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly) 572 { 573 // Cache the configs we select as they wont change: 574 static EGLConfig roPixmapRGBConfig = 0; 575 static EGLConfig roPixmapRGBAConfig = 0; 576 static EGLConfig rwPixmapRGBConfig = 0; 577 static EGLConfig rwPixmapRGBAConfig = 0; 578 579 EGLConfig* targetConfig; 580 581 if (hasAlpha) { 582 if (readOnly) 583 targetConfig = &roPixmapRGBAConfig; 584 else 585 targetConfig = &rwPixmapRGBAConfig; 586 } 587 else { 588 if (readOnly) 589 targetConfig = &roPixmapRGBConfig; 590 else 591 targetConfig = &rwPixmapRGBConfig; 592 } 593 594 if (*targetConfig == 0) { 595 QEglProperties configAttribs; 596 configAttribs.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT); 597 configAttribs.setRenderableType(QEgl::OpenGL); 598 if (hasAlpha) 599 configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); 600 else 601 configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); 602 603 // If this is going to be a render target, it needs to have a depth, stencil & sample buffer 604 if (!readOnly) { 605 configAttribs.setValue(EGL_DEPTH_SIZE, 1); 606 configAttribs.setValue(EGL_STENCIL_SIZE, 1); 607 configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1); 608 } 609 610 EGLint configCount = 0; 611 do { 612 eglChooseConfig(QEglContext::display(), configAttribs.properties(), targetConfig, 1, &configCount); 613 if (configCount > 0) { 614 // Got one 615 qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" ) 616 << "config (" << int(*targetConfig) << ") to create a pixmap surface:"; 617 618 // QEglProperties configProps(*targetConfig); 619 // qDebug() << configProps.toString(); 620 break; 621 } 622 qWarning("choosePixmapConfig() - No suitible config found, reducing requirements"); 623 } while (configAttribs.reduceConfiguration()); 624 } 625 626 if (*targetConfig == 0) 627 qWarning("choosePixmapConfig() - Couldn't find a suitable config"); 628 629 return *targetConfig; 630 } 631 632 bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly) 633 { 634 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 635 QX11PixmapData* pixmapData = static_cast<QX11PixmapData*>(pmd); 636 637 bool hasAlpha = pixmapData->hasAlphaChannel(); 638 639 EGLConfig pixmapConfig = qt_chooseEGLConfigForPixmap(hasAlpha, readOnly); 640 641 QEglProperties pixmapAttribs; 642 643 // If the pixmap can't be bound to a texture, it's pretty useless 644 pixmapAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); 645 if (hasAlpha) 646 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); 647 else 648 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); 649 650 EGLSurface pixmapSurface; 651 pixmapSurface = eglCreatePixmapSurface(QEglContext::display(), 652 pixmapConfig, 653 (EGLNativePixmapType) pixmapData->handle(), 654 pixmapAttribs.properties()); 655 // qDebug("qt_createEGLSurfaceForPixmap() created surface 0x%x for pixmap 0x%x", 656 // pixmapSurface, pixmapData->handle()); 657 if (pixmapSurface == EGL_NO_SURFACE) { 658 qWarning() << "Failed to create a pixmap surface using config" << (int)pixmapConfig 659 << ":" << QEglContext::errorString(eglGetError()); 660 return false; 661 } 662 663 static bool doneOnce = false; 664 if (!doneOnce) { 665 // Make sure QGLTextureCache is instanciated so it can install cleanup hooks 666 // which cleanup the EGL surface. 667 QGLTextureCache::instance(); 668 doneOnce = true; 669 } 670 671 Q_ASSERT(sizeof(Qt::HANDLE) >= sizeof(EGLSurface)); // Just to make totally sure! 672 pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface; 673 QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData); // Make sure the cleanup hook gets called 674 675 return true; 676 } 677 678 679 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key, 358 359 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, 680 360 QGLContext::BindOptions options) 681 361 { … … 686 366 return 0; 687 367 688 Q_ASSERT(pd->classId() == QPixmapData::X11Class);689 368 690 369 static bool checkedForTFP = false; 691 370 static bool haveTFP = false; 371 static bool checkedForEglImageTFP = false; 372 static bool haveEglImageTFP = false; 373 374 375 if (!checkedForEglImageTFP) { 376 checkedForEglImageTFP = true; 377 378 // We need to be able to create an EGLImage from a native pixmap, which was split 379 // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have 380 // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must 381 // check we have the EGLImage from pixmap functionality. 382 if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) { 383 384 // Being able to create an EGLImage from a native pixmap is also pretty useless 385 // without the ability to bind that EGLImage as a texture, which is provided by 386 // the GL_OES_EGL_image extension, which we try to resolve here: 387 haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q); 388 389 if (haveEglImageTFP) 390 qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!"); 391 } 392 } 692 393 693 394 if (!checkedForTFP) { 694 395 // Check for texture_from_pixmap egl extension 695 396 checkedForTFP = true; 696 if ( eglContext->hasExtension("EGL_NOKIA_texture_from_pixmap") ||697 eglContext->hasExtension("EGL_EXT_texture_from_pixmap"))397 if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") || 398 QEgl::hasExtension("EGL_EXT_texture_from_pixmap")) 698 399 { 699 400 qDebug("Found texture_from_pixmap EGL extension!"); … … 702 403 } 703 404 704 if (!haveTFP )405 if (!haveTFP && !haveEglImageTFP) 705 406 return 0; 706 407 707 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pd); 708 408 409 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); 410 Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); 709 411 bool hasAlpha = pixmapData->hasAlphaChannel(); 710 711 // Check to see if the surface is still valid 712 if (pixmapData->gl_surface && 713 hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) 714 { 715 // Surface is invalid! 716 destroyGlSurfaceForPixmap(pixmapData); 717 } 718 719 if (pixmapData->gl_surface == 0) { 720 bool success = qt_createEGLSurfaceForPixmap(pixmapData, true); 721 if (!success) { 722 haveTFP = false; 723 return 0; 724 } 725 } 726 727 Q_ASSERT(pixmapData->gl_surface); 728 412 bool pixmapHasValidSurface = false; 413 bool textureIsBound = false; 729 414 GLuint textureId; 730 415 glGenTextures(1, &textureId); 731 416 glBindTexture(GL_TEXTURE_2D, textureId); 732 417 733 // bind the egl pixmap surface to a texture 734 EGLBoolean success; 735 success = eglBindTexImage(eglContext->display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); 736 if (success == EGL_FALSE) { 737 qWarning() << "eglBindTexImage() failed:" << eglContext->errorString(eglGetError()); 738 eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface); 739 pixmapData->gl_surface = (Qt::HANDLE)EGL_NO_SURFACE; 740 haveTFP = false; 741 return 0; 742 } 743 744 QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); 745 pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; 746 747 // We assume the cost of bound pixmaps is zero 748 QGLTextureCache::instance()->insert(q, key, texture, 0); 749 750 glBindTexture(GL_TEXTURE_2D, textureId); 418 if (haveTFP && pixmapData->gl_surface && 419 hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) 420 { 421 pixmapHasValidSurface = true; 422 } 423 424 // If we already have a valid EGL surface for the pixmap, we should use it 425 if (pixmapHasValidSurface) { 426 EGLBoolean success; 427 success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); 428 if (success == EGL_FALSE) { 429 qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); 430 eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); 431 pixmapData->gl_surface = (void*)EGL_NO_SURFACE; 432 } else 433 textureIsBound = true; 434 } 435 436 // If the pixmap doesn't already have a valid surface, try binding it via EGLImage 437 // first, as going through EGLImage should be faster and better supported: 438 if (!textureIsBound && haveEglImageTFP) { 439 EGLImageKHR eglImage; 440 441 EGLint attribs[] = { 442 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 443 EGL_NONE 444 }; 445 eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, 446 (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs); 447 448 QGLContext* ctx = q; 449 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); 450 451 GLint err = glGetError(); 452 if (err == GL_NO_ERROR) 453 textureIsBound = true; 454 455 // Once the egl image is bound, the texture becomes a new sibling image and we can safely 456 // destroy the EGLImage we created for the pixmap: 457 if (eglImage != EGL_NO_IMAGE_KHR) 458 QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); 459 } 460 461 if (!textureIsBound && haveTFP) { 462 // Check to see if the surface is still valid 463 if (pixmapData->gl_surface && 464 hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) 465 { 466 // Surface is invalid! 467 destroyGlSurfaceForPixmap(pixmapData); 468 } 469 470 if (pixmapData->gl_surface == 0) { 471 EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, 472 QEgl::OpenGL, 473 hasAlpha ? QEgl::Translucent : QEgl::NoOptions); 474 475 pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); 476 if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) 477 return false; 478 } 479 480 EGLBoolean success; 481 success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); 482 if (success == EGL_FALSE) { 483 qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); 484 eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); 485 pixmapData->gl_surface = (void*)EGL_NO_SURFACE; 486 haveTFP = false; // If TFP isn't working, disable it's use 487 } else 488 textureIsBound = true; 489 } 490 491 QGLTexture *texture = 0; 492 493 if (textureIsBound) { 494 texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); 495 pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; 496 497 // We assume the cost of bound pixmaps is zero 498 QGLTextureCache::instance()->insert(q, key, texture, 0); 499 500 glBindTexture(GL_TEXTURE_2D, textureId); 501 } else 502 glDeleteTextures(1, &textureId); 503 751 504 return texture; 752 505 } 506 753 507 754 508 void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) … … 758 512 if (pixmapData->gl_surface) { 759 513 EGLBoolean success; 760 success = eglDestroySurface(QEgl Context::display(), (EGLSurface)pixmapData->gl_surface);514 success = eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); 761 515 if (success == EGL_FALSE) { 762 516 qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " 763 << QEgl Context::errorString(eglGetError());517 << QEgl::errorString(); 764 518 } 765 519 pixmapData->gl_surface = 0; … … 773 527 if (pixmapData->gl_surface) { 774 528 EGLBoolean success; 775 success = eglReleaseTexImage(QEgl Context::display(),529 success = eglReleaseTexImage(QEgl::display(), 776 530 (EGLSurface)pixmapData->gl_surface, 777 531 EGL_BACK_BUFFER); 778 532 if (success == EGL_FALSE) { 779 533 qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " 780 << QEgl Context::errorString(eglGetError());534 << QEgl::errorString(); 781 535 } 782 536 } -
trunk/src/opengl/qglcolormap.cpp
r651 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) -
trunk/src/opengl/qglcolormap.h
r651 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) -
trunk/src/opengl/qglextensions.cpp
r651 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) … … 192 192 bool qt_resolve_buffer_extensions(QGLContext *ctx) 193 193 { 194 if (glMapBufferARB && glUnmapBufferARB 195 #if !defined(QT_OPENGL_ES_2) 196 && glBindBuffer && glDeleteBuffers && glGenBuffers && glBufferData 197 #endif 198 ) 199 return true; 200 201 #if !defined(QT_OPENGL_ES_2) 194 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 195 if (glBindBuffer && glDeleteBuffers && glGenBuffers && glBufferData 196 && glBufferSubData && glGetBufferParameteriv) 197 return true; 198 #endif 199 200 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 202 201 glBindBuffer = (_glBindBuffer) qt_gl_getProcAddressARB(ctx, "glBindBuffer"); 203 202 glDeleteBuffers = (_glDeleteBuffers) qt_gl_getProcAddressARB(ctx, "glDeleteBuffers"); 204 203 glGenBuffers = (_glGenBuffers) qt_gl_getProcAddressARB(ctx, "glGenBuffers"); 205 204 glBufferData = (_glBufferData) qt_gl_getProcAddressARB(ctx, "glBufferData"); 205 glBufferSubData = (_glBufferSubData) qt_gl_getProcAddressARB(ctx, "glBufferSubData"); 206 glGetBufferSubData = (_glGetBufferSubData) qt_gl_getProcAddressARB(ctx, "glGetBufferSubData"); 207 glGetBufferParameteriv = (_glGetBufferParameteriv) qt_gl_getProcAddressARB(ctx, "glGetBufferParameteriv"); 206 208 #endif 207 209 glMapBufferARB = (_glMapBufferARB) qt_gl_getProcAddressARB(ctx, "glMapBuffer"); 208 210 glUnmapBufferARB = (_glUnmapBufferARB) qt_gl_getProcAddressARB(ctx, "glUnmapBuffer"); 209 211 210 return glMapBufferARB 211 && glUnmapBufferARB 212 #if !defined(QT_OPENGL_ES_2) 213 && glBindBuffer 212 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 213 return glBindBuffer 214 214 && glDeleteBuffers 215 215 && glGenBuffers 216 216 && glBufferData 217 #endif 218 ; 219 } 217 && glBufferSubData 218 && glGetBufferParameteriv; 219 // glGetBufferSubData() is optional 220 #else 221 return true; 222 #endif 223 } 224 225 #ifndef QT_NO_EGL 226 bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx) 227 { 228 if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES) 229 return true; 230 glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES")); 231 glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES")); 232 return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES; 233 } 234 #endif 220 235 221 236 bool qt_resolve_glsl_extensions(QGLContext *ctx) 222 237 { 238 223 239 #if defined(QT_OPENGL_ES_2) 224 240 // The GLSL shader functions are always present in OpenGL/ES 2.0. … … 233 249 if (glCreateShader) 234 250 return true; 251 252 // Geometry shaders are optional... 253 glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT")); 254 glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT")); 255 glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT")); 256 glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT")); 257 258 // Must at least have the FragmentShader extension to continue. 259 if (!(QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)) 260 return false; 235 261 236 262 glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShader")); -
trunk/src/opengl/qglextensions_p.h
r651 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) … … 69 69 #endif 70 70 71 #ifndef QT_NO_EGL 72 // Needed for EGLImageKHR definition: 73 #include <QtGui/private/qegl_p.h> 74 #endif 75 71 76 #include <QtCore/qglobal.h> 72 77 73 78 #ifndef GL_ARB_vertex_buffer_object 79 typedef ptrdiff_t GLintptrARB; 74 80 typedef ptrdiff_t GLsizeiptrARB; 75 81 #endif … … 79 85 #endif 80 86 81 // ARB_ pixel_buffer_object87 // ARB_vertex_buffer_object 82 88 typedef void (APIENTRY *_glBindBuffer) (GLenum, GLuint); 83 89 typedef void (APIENTRY *_glDeleteBuffers) (GLsizei, const GLuint *); 84 90 typedef void (APIENTRY *_glGenBuffers) (GLsizei, GLuint *); 85 91 typedef void (APIENTRY *_glBufferData) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); 92 typedef void (APIENTRY *_glBufferSubData) (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); 93 typedef void (APIENTRY *_glGetBufferSubData) (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); 94 typedef void (APIENTRY *_glGetBufferParameteriv) (GLenum, GLenum, GLint *); 86 95 typedef GLvoid* (APIENTRY *_glMapBufferARB) (GLenum, GLenum); 87 96 typedef GLboolean (APIENTRY *_glUnmapBufferARB) (GLenum); 97 // We can call the buffer functions directly in OpenGL/ES 1.1 or higher, 98 // but all other platforms need to resolve the extensions. 99 #if defined(QT_OPENGL_ES) 100 #if defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1) 101 #define QGL_RESOLVE_BUFFER_FUNCS 1 102 #endif 103 #else 104 #define QGL_RESOLVE_BUFFER_FUNCS 1 105 #endif 88 106 89 107 // ARB_fragment_program … … 185 203 GLenum internalformat, GLsizei width, GLsizei height); 186 204 205 // GL_EXT_geometry_shader4 206 typedef void (APIENTRY *_glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value); 207 typedef void (APIENTRY *_glFramebufferTextureEXT)(GLenum target, GLenum attachment, 208 GLuint texture, GLint level); 209 typedef void (APIENTRY *_glFramebufferTextureLayerEXT)(GLenum target, GLenum attachment, 210 GLuint texture, GLint level, GLint layer); 211 typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum attachment, 212 GLuint texture, GLint level, GLenum face); 213 187 214 // ARB_texture_compression 188 215 typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, 189 216 GLsizei, GLint, GLsizei, const GLvoid *); 217 218 #ifndef QT_NO_EGL 219 // OES_EGL_image 220 // Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES 221 // type, which the EGL image should be cast to. 222 typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR); 223 typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR); 224 #endif 190 225 191 226 QT_BEGIN_NAMESPACE … … 286 321 287 322 // Buffer objects: 288 #if !defined(QT_OPENGL_ES_2)323 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 289 324 qt_glBindBuffer = 0; 290 325 qt_glDeleteBuffers = 0; 291 326 qt_glGenBuffers = 0; 292 327 qt_glBufferData = 0; 328 qt_glBufferSubData = 0; 329 qt_glGetBufferSubData = 0; 330 qt_glGetBufferParameteriv = 0; 293 331 #endif 294 332 qt_glMapBufferARB = 0; 295 333 qt_glUnmapBufferARB = 0; 296 334 335 qt_glProgramParameteriEXT = 0; 336 qt_glFramebufferTextureEXT = 0; 337 qt_glFramebufferTextureLayerEXT = 0; 338 qt_glFramebufferTextureFaceEXT = 0; 297 339 #if !defined(QT_OPENGL_ES) 298 340 // Texture compression 299 341 qt_glCompressedTexImage2DARB = 0; 342 #endif 343 344 #ifndef QT_NO_EGL 345 // OES_EGL_image 346 qt_glEGLImageTargetTexture2DOES = 0; 347 qt_glEGLImageTargetRenderbufferStorageOES = 0; 300 348 #endif 301 349 } … … 398 446 399 447 // Buffer objects 400 #if !defined(QT_OPENGL_ES_2)448 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 401 449 _glBindBuffer qt_glBindBuffer; 402 450 _glDeleteBuffers qt_glDeleteBuffers; 403 451 _glGenBuffers qt_glGenBuffers; 404 452 _glBufferData qt_glBufferData; 453 _glBufferSubData qt_glBufferSubData; 454 _glGetBufferSubData qt_glGetBufferSubData; 455 _glGetBufferParameteriv qt_glGetBufferParameteriv; 405 456 #endif 406 457 _glMapBufferARB qt_glMapBufferARB; 407 458 _glUnmapBufferARB qt_glUnmapBufferARB; 408 459 460 // Geometry shaders... 461 _glProgramParameteriEXT qt_glProgramParameteriEXT; 462 _glFramebufferTextureEXT qt_glFramebufferTextureEXT; 463 _glFramebufferTextureLayerEXT qt_glFramebufferTextureLayerEXT; 464 _glFramebufferTextureFaceEXT qt_glFramebufferTextureFaceEXT; 409 465 #if !defined(QT_OPENGL_ES) 410 466 // Texture compression 411 467 _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB; 412 468 #endif 469 470 #ifndef QT_NO_EGL 471 // OES_EGL_image 472 _glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES; 473 _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES; 474 #endif 413 475 }; 414 476 415 477 416 478 // OpenGL constants 479 480 #ifndef GL_ARRAY_BUFFER 481 #define GL_ARRAY_BUFFER 0x8892 482 #endif 483 484 #ifndef GL_STATIC_DRAW 485 #define GL_STATIC_DRAW 0x88E4 486 #endif 417 487 418 488 /* NV_texture_rectangle */ … … 429 499 430 500 #ifndef GL_RGB16 431 #define GL_RGB16 32852501 #define GL_RGB16 0x8054 432 502 #endif 433 503 434 504 #ifndef GL_UNSIGNED_SHORT_5_6_5 435 #define GL_UNSIGNED_SHORT_5_6_5 33635505 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 436 506 #endif 437 507 … … 492 562 #ifndef GL_TEXTURE1 493 563 #define GL_TEXTURE1 0x84C1 564 #endif 565 566 #ifndef GL_DEPTH_COMPONENT16 567 #define GL_DEPTH_COMPONENT16 0x81A5 568 #endif 569 570 #ifndef GL_DEPTH_COMPONENT24_OES 571 #define GL_DEPTH_COMPONENT24_OES 0x81A6 494 572 #endif 495 573 … … 600 678 #endif 601 679 680 #ifndef GL_VERSION_1_5 681 #define GL_ARRAY_BUFFER 0x8892 682 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 683 #define GL_STREAM_DRAW 0x88E0 684 #define GL_STREAM_READ 0x88E1 685 #define GL_STREAM_COPY 0x88E2 686 #define GL_STATIC_DRAW 0x88E4 687 #define GL_STATIC_READ 0x88E5 688 #define GL_STATIC_COPY 0x88E6 689 #define GL_DYNAMIC_DRAW 0x88E8 690 #define GL_DYNAMIC_READ 0x88E9 691 #define GL_DYNAMIC_COPY 0x88EA 692 #endif 693 602 694 #ifndef GL_VERSION_2_0 603 695 #define GL_FRAGMENT_SHADER 0x8B30 … … 629 721 #endif 630 722 723 // Geometry shader defines 724 #ifndef GL_GEOMETRY_SHADER_EXT 725 # define GL_GEOMETRY_SHADER_EXT 0x8DD9 726 # define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA 727 # define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB 728 # define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC 729 # define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 730 # define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD 731 # define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE 732 # define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B 733 # define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF 734 # define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 735 # define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 736 # define GL_LINES_ADJACENCY_EXT 0xA 737 # define GL_LINE_STRIP_ADJACENCY_EXT 0xB 738 # define GL_TRIANGLES_ADJACENCY_EXT 0xC 739 # define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD 740 # define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 741 # define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 742 # define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 743 # define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 744 # define GL_PROGRAM_POINT_SIZE_EXT 0x8642 745 #endif 631 746 632 747 #if !defined(QT_OPENGL_ES_2) … … 668 783 669 784 // Buffer objects 670 #if !defined(QT_OPENGL_ES_2)785 #if defined(QGL_RESOLVE_BUFFER_FUNCS) 671 786 #define glBindBuffer QGLContextPrivate::extensionFuncs(ctx).qt_glBindBuffer 672 787 #define glDeleteBuffers QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteBuffers 673 788 #define glGenBuffers QGLContextPrivate::extensionFuncs(ctx).qt_glGenBuffers 674 789 #define glBufferData QGLContextPrivate::extensionFuncs(ctx).qt_glBufferData 790 #define glBufferSubData QGLContextPrivate::extensionFuncs(ctx).qt_glBufferSubData 791 #define glGetBufferSubData QGLContextPrivate::extensionFuncs(ctx).qt_glGetBufferSubData 792 #define glGetBufferParameteriv QGLContextPrivate::extensionFuncs(ctx).qt_glGetBufferParameteriv 675 793 #endif 676 794 #define glMapBufferARB QGLContextPrivate::extensionFuncs(ctx).qt_glMapBufferARB … … 746 864 #endif 747 865 866 #define glProgramParameteriEXT QGLContextPrivate::extensionFuncs(ctx).qt_glProgramParameteriEXT 867 #define glFramebufferTextureEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureEXT 868 #define glFramebufferTextureLayerEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureLayerEXT 869 #define glFramebufferTextureFaceEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureFaceEXT 870 748 871 #if !defined(QT_OPENGL_ES) 749 872 #define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB 873 #endif 874 875 #ifndef QT_NO_EGL 876 // OES_EGL_image 877 #define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES 878 #define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES 750 879 #endif 751 880 … … 760 889 bool qt_resolve_glsl_extensions(QGLContext *ctx); 761 890 891 #ifndef QT_NO_EGL 892 Q_OPENGL_EXPORT bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx); 893 #endif 894 762 895 QT_END_NAMESPACE 763 896 -
trunk/src/opengl/qglframebufferobject.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) … … 45 45 #include <qdebug.h> 46 46 #include <private/qgl_p.h> 47 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)47 #if !defined(QT_OPENGL_ES_1) 48 48 #include <private/qpaintengineex_opengl2_p.h> 49 49 #endif … … 56 56 #include <qlibrary.h> 57 57 #include <qimage.h> 58 59 #ifdef QT_OPENGL_ES_1_CL60 #include "qgl_cl_p.h"61 #endif62 58 63 59 QT_BEGIN_NAMESPACE … … 133 129 On OpenGL/ES systems, the default internal format is \c GL_RGBA. 134 130 135 \sa samples(), attachment(), target(),internalTextureFormat()131 \sa samples(), attachment(), internalTextureFormat() 136 132 */ 137 133 … … 450 446 glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); 451 447 452 samples = qBound( 1, int(samples), int(maxSamples));448 samples = qBound(0, int(samples), int(maxSamples)); 453 449 454 450 glGenRenderbuffers(1, &color_buffer); 455 451 glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); 456 if (glRenderbufferStorageMultisampleEXT ) {452 if (glRenderbufferStorageMultisampleEXT && samples > 0) { 457 453 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 458 454 internal_format, size.width(), size.height()); … … 473 469 } 474 470 471 // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a 472 // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer 473 // might not be supported while separate buffers are, according to QTBUG-12861. 474 475 475 if (attachment == QGLFramebufferObject::CombinedDepthStencil 476 476 && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { 477 477 // depth and stencil buffer needs another extension 478 glGenRenderbuffers(1, &depth_ stencil_buffer);479 Q_ASSERT(!glIsRenderbuffer(depth_ stencil_buffer));480 glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_ stencil_buffer);481 Q_ASSERT(glIsRenderbuffer(depth_ stencil_buffer));478 glGenRenderbuffers(1, &depth_buffer); 479 Q_ASSERT(!glIsRenderbuffer(depth_buffer)); 480 glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); 481 Q_ASSERT(glIsRenderbuffer(depth_buffer)); 482 482 if (samples != 0 && glRenderbufferStorageMultisampleEXT) 483 483 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, … … 487 487 GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); 488 488 489 GLint i = 0; 490 glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); 489 stencil_buffer = depth_buffer; 491 490 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 492 GL_RENDERBUFFER_EXT, depth_ stencil_buffer);491 GL_RENDERBUFFER_EXT, depth_buffer); 493 492 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, 494 GL_RENDERBUFFER_EXT, depth_stencil_buffer); 495 fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; 493 GL_RENDERBUFFER_EXT, stencil_buffer); 496 494 497 495 valid = checkFramebufferStatus(); 498 if (!valid) 499 glDeleteRenderbuffers(1, &depth_stencil_buffer); 500 } else if (attachment == QGLFramebufferObject::Depth 501 || attachment == QGLFramebufferObject::CombinedDepthStencil) 496 if (!valid) { 497 glDeleteRenderbuffers(1, &depth_buffer); 498 stencil_buffer = depth_buffer = 0; 499 } 500 } 501 502 if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil 503 || (attachment == QGLFramebufferObject::Depth))) 502 504 { 503 glGenRenderbuffers(1, &depth_ stencil_buffer);504 Q_ASSERT(!glIsRenderbuffer(depth_ stencil_buffer));505 glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_ stencil_buffer);506 Q_ASSERT(glIsRenderbuffer(depth_ stencil_buffer));505 glGenRenderbuffers(1, &depth_buffer); 506 Q_ASSERT(!glIsRenderbuffer(depth_buffer)); 507 glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); 508 Q_ASSERT(glIsRenderbuffer(depth_buffer)); 507 509 if (samples != 0 && glRenderbufferStorageMultisampleEXT) { 508 510 #ifdef QT_OPENGL_ES 509 #define GL_DEPTH_COMPONENT16 0x81A5 510 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 511 GL_DEPTH_COMPONENT16, size.width(), size.height()); 511 if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { 512 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 513 GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); 514 } else { 515 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 516 GL_DEPTH_COMPONENT16, size.width(), size.height()); 517 } 512 518 #else 513 519 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, … … 516 522 } else { 517 523 #ifdef QT_OPENGL_ES 518 #define GL_DEPTH_COMPONENT16 0x81A5 519 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); 524 if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { 525 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, 526 size.width(), size.height()); 527 } else { 528 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, 529 size.width(), size.height()); 530 } 520 531 #else 521 532 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); 522 533 #endif 523 534 } 524 GLint i = 0;525 glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);526 535 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 527 GL_RENDERBUFFER_EXT, depth_stencil_buffer); 536 GL_RENDERBUFFER_EXT, depth_buffer); 537 valid = checkFramebufferStatus(); 538 if (!valid) { 539 glDeleteRenderbuffers(1, &depth_buffer); 540 depth_buffer = 0; 541 } 542 } 543 544 if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { 545 glGenRenderbuffers(1, &stencil_buffer); 546 Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); 547 glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); 548 Q_ASSERT(glIsRenderbuffer(stencil_buffer)); 549 if (samples != 0 && glRenderbufferStorageMultisampleEXT) { 550 #ifdef QT_OPENGL_ES 551 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 552 GL_STENCIL_INDEX8_EXT, size.width(), size.height()); 553 #else 554 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, 555 GL_STENCIL_INDEX, size.width(), size.height()); 556 #endif 557 } else { 558 #ifdef QT_OPENGL_ES 559 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, 560 size.width(), size.height()); 561 #else 562 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, 563 size.width(), size.height()); 564 #endif 565 } 566 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, 567 GL_RENDERBUFFER_EXT, stencil_buffer); 568 valid = checkFramebufferStatus(); 569 if (!valid) { 570 glDeleteRenderbuffers(1, &stencil_buffer); 571 stencil_buffer = 0; 572 } 573 } 574 575 // The FBO might have become valid after removing the depth or stencil buffer. 576 valid = checkFramebufferStatus(); 577 578 if (depth_buffer && stencil_buffer) { 579 fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; 580 } else if (depth_buffer) { 528 581 fbo_attachment = QGLFramebufferObject::Depth; 529 valid = checkFramebufferStatus();530 if (!valid)531 glDeleteRenderbuffers(1, &depth_stencil_buffer);532 582 } else { 533 583 fbo_attachment = QGLFramebufferObject::NoAttachment; … … 540 590 else 541 591 glDeleteTextures(1, &texture); 592 if (depth_buffer) 593 glDeleteRenderbuffers(1, &depth_buffer); 594 if (stencil_buffer && depth_buffer != stencil_buffer) 595 glDeleteRenderbuffers(1, &stencil_buffer); 542 596 glDeleteFramebuffers(1, &fbo); 543 597 fbo_guard.setId(0); … … 822 876 if (d->color_buffer) 823 877 glDeleteRenderbuffers(1, &d->color_buffer); 824 if (d->depth_stencil_buffer) 825 glDeleteRenderbuffers(1, &d->depth_stencil_buffer); 878 if (d->depth_buffer) 879 glDeleteRenderbuffers(1, &d->depth_buffer); 880 if (d->stencil_buffer && d->stencil_buffer != d->depth_buffer) 881 glDeleteRenderbuffers(1, &d->stencil_buffer); 826 882 GLuint fbo = d->fbo(); 827 883 glDeleteFramebuffers(1, &fbo); … … 988 1044 } 989 1045 990 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)1046 #if !defined(QT_OPENGL_ES_1) 991 1047 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) 992 1048 #endif … … 1003 1059 return d->engine; 1004 1060 1005 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)1061 #if !defined(QT_OPENGL_ES_1) 1006 1062 #if !defined (QT_OPENGL_ES_2) 1007 1063 if (qt_gl_preferGL2Engine()) { … … 1029 1085 1030 1086 /*! 1087 \fn bool QGLFramebufferObject::bindDefault() 1088 \internal 1089 1090 Switches rendering back to the default, windowing system provided 1091 framebuffer. 1092 Returns true upon success, false otherwise. 1093 1094 \sa bind(), release() 1095 */ 1096 bool QGLFramebufferObject::bindDefault() 1097 { 1098 QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); 1099 1100 if (ctx) { 1101 bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); 1102 if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) 1103 return false; 1104 1105 ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo; 1106 glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->default_fbo); 1107 #ifdef QT_DEBUG 1108 } else { 1109 qWarning("QGLFramebufferObject::bindDefault() called without current context."); 1110 #endif 1111 } 1112 1113 return ctx != 0; 1114 } 1115 1116 /*! 1031 1117 \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects() 1032 1118 … … 1086 1172 #endif 1087 1173 1088 extern int qt_defaultDpiX();1089 extern int qt_defaultDpiY();1174 Q_DECL_IMPORT extern int qt_defaultDpiX(); 1175 Q_DECL_IMPORT extern int qt_defaultDpiY(); 1090 1176 1091 1177 /*! \reimp */ -
trunk/src/opengl/qglframebufferobject.h
r651 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) … … 109 109 GLuint handle() const; 110 110 111 static bool bindDefault(); 112 111 113 static bool hasOpenGLFramebufferObjects(); 112 114 -
trunk/src/opengl/qglframebufferobject_p.h
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) … … 127 127 { 128 128 public: 129 QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_ stencil_buffer(0)129 QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_buffer(0), stencil_buffer(0) 130 130 , color_buffer(0), valid(false), engine(0) {} 131 131 ~QGLFramebufferObjectPrivate() {} … … 137 137 QGLSharedResourceGuard fbo_guard; 138 138 GLuint texture; 139 GLuint depth_stencil_buffer; 139 GLuint depth_buffer; 140 GLuint stencil_buffer; 140 141 GLuint color_buffer; 141 142 GLenum target; -
trunk/src/opengl/qglpaintdevice.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) … … 49 49 #endif 50 50 51 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)51 #if !defined(QT_OPENGL_ES_1) 52 52 #include <private/qpixmapdata_gl_p.h> 53 #endif54 55 #if defined(QT_OPENGL_ES_1_CL)56 #include "qgl_cl_p.h"57 53 #endif 58 54 … … 68 64 } 69 65 66 int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const 67 { 68 switch(metric) { 69 case PdmWidth: 70 return size().width(); 71 case PdmHeight: 72 return size().height(); 73 case PdmDepth: { 74 const QGLFormat f = format(); 75 return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize(); 76 } 77 default: 78 qWarning("QGLPaintDevice::metric() - metric %d not known", metric); 79 return 0; 80 } 81 } 70 82 71 83 void QGLPaintDevice::beginPaint() … … 164 176 glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); 165 177 } 166 glClear(GL_COLOR_BUFFER_BIT); 178 if (context()->d_func()->workaround_needsFullClearOnEveryFrame) 179 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 180 else 181 glClear(GL_COLOR_BUFFER_BIT); 167 182 } 168 183 } … … 204 219 break; 205 220 case QInternal::Pixmap: { 206 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)221 #if !defined(QT_OPENGL_ES_1) 207 222 QPixmapData* pmd = static_cast<QPixmap*>(pd)->pixmapData(); 208 223 if (pmd->classId() == QPixmapData::OpenGLClass) -
trunk/src/opengl/qglpaintdevice_p.h
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) … … 82 82 83 83 protected: 84 int metric(QPaintDevice::PaintDeviceMetric metric) const; 84 85 GLuint m_previousFBO; 85 86 GLuint m_thisFBO; -
trunk/src/opengl/qglpixelbuffer.cpp
r651 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) … … 68 68 additional copy operations. This is supported only on Windows 69 69 and Mac OS X systems that provide the \c render_texture 70 extension. 70 extension. Note that under Windows, a multi-sampled pbuffer 71 can't be used in conjunction with the \c render_texture 72 extension. If a multi-sampled pbuffer is requested under 73 Windows, the \c render_texture extension is turned off for that 74 pbuffer. 75 76 71 77 \endlist 72 78 … … 79 85 #include <QtCore/qglobal.h> 80 86 81 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)87 #if !defined(QT_OPENGL_ES_1) 82 88 #include <private/qpaintengineex_opengl2_p.h> 83 89 #endif … … 138 144 qctx->d_func()->dc = dc; 139 145 qctx->d_func()->rc = ctx; 140 #elif (defined(Q_WS_X11) && !defined(QT_OPENGL_ES))146 #elif (defined(Q_WS_X11) && defined(QT_NO_EGL)) 141 147 qctx->d_func()->cx = ctx; 142 148 qctx->d_func()->pbuf = (void *) pbuf; … … 145 151 qctx->d_func()->cx = ctx; 146 152 qctx->d_func()->vi = 0; 147 #elif defined(QT_OPENGL_ES)153 #elif !defined(QT_NO_EGL) 148 154 qctx->d_func()->eglContext = ctx; 149 155 qctx->d_func()->eglSurface = pbuf; … … 255 261 */ 256 262 257 #if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && !defined(QT_OPENGL_ES)263 #if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL) 258 264 GLuint QGLPixelBuffer::generateDynamicTexture() const 259 265 { … … 388 394 } 389 395 390 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)396 #if !defined(QT_OPENGL_ES_1) 391 397 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) 392 398 #endif … … 399 405 QPaintEngine *QGLPixelBuffer::paintEngine() const 400 406 { 401 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)407 #if defined(QT_OPENGL_ES_1) 402 408 return qt_buffer_engine(); 403 409 #elif defined(QT_OPENGL_ES_2) … … 411 417 } 412 418 413 extern int qt_defaultDpiX();414 extern int qt_defaultDpiY();419 Q_DECL_IMPORT extern int qt_defaultDpiX(); 420 Q_DECL_IMPORT extern int qt_defaultDpiY(); 415 421 416 422 /*! \reimp */ -
trunk/src/opengl/qglpixelbuffer.h
r651 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) … … 113 113 friend class QGLPaintDevice; 114 114 friend class QGLPBufferGLPaintDevice; 115 friend class QGLContextPrivate; 115 116 }; 116 117 -
trunk/src/opengl/qglpixelbuffer_egl.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) … … 48 48 #include <private/qgl_p.h> 49 49 50 #ifdef QT_OPENGL_ES_1_CL51 #include "qgl_cl_p.h"52 #endif53 54 50 QT_BEGIN_NAMESPACE 55 51 … … 79 75 ctx->setConfig(shareContext->config()); 80 76 #if QGL_RENDER_TEXTURE 81 EGLint value = EGL_FALSE; 82 if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA, &value) && value) 77 if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE) 83 78 textureFormat = EGL_TEXTURE_RGBA; 84 else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB , &value) && value)79 else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE) 85 80 textureFormat = EGL_TEXTURE_RGB; 86 81 #endif 87 82 } else { 88 83 QEglProperties configProps; 89 qt_egl_set_format(configProps, QInternal::Pbuffer, f); 84 qt_eglproperties_set_glformat(configProps, f); 85 configProps.setDeviceType(QInternal::Pbuffer); 90 86 configProps.setRenderableType(ctx->api()); 91 87 bool ok = false; … … 117 113 118 114 // Retrieve the actual format properties. 119 qt_ egl_update_format(*ctx, format);115 qt_glformat_from_eglconfig(format, ctx->config()); 120 116 121 117 // Create the attributes needed for the pbuffer. … … 142 138 #endif 143 139 if (pbuf == EGL_NO_SURFACE) { 144 qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl Context::errorString(eglGetError());140 qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString(); 145 141 return false; 146 142 } … … 209 205 { 210 206 // See if we have at least 1 configuration that matches the default format. 211 EGLDisplay dpy = QEgl Context::display();207 EGLDisplay dpy = QEgl::display(); 212 208 if (dpy == EGL_NO_DISPLAY) 213 209 return false; 214 210 QEglProperties configProps; 215 qt_egl_set_format(configProps, QInternal::Pbuffer, QGLFormat::defaultFormat()); 211 qt_eglproperties_set_glformat(configProps, QGLFormat::defaultFormat()); 212 configProps.setDeviceType(QInternal::Pbuffer); 216 213 configProps.setRenderableType(QEgl::OpenGL); 217 214 do { -
trunk/src/opengl/qglpixelbuffer_mac.mm
r651 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) -
trunk/src/opengl/qglpixelbuffer_p.h
r651 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) … … 61 61 #include <private/qglpaintdevice_p.h> 62 62 63 #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)63 #if defined(Q_WS_X11) && defined(QT_NO_EGL) 64 64 #include <GL/glx.h> 65 65 … … 128 128 #elif defined(Q_WS_WIN) 129 129 DECLARE_HANDLE(HPBUFFERARB); 130 #elif defined(QT_OPENGL_ES_2) 131 #include <EGL/egl.h> 132 #elif defined(QT_OPENGL_ES) 133 #include <GLES/egl.h> 130 #elif !defined(QT_NO_EGL) 131 #include <QtGui/private/qegl_p.h> 134 132 #endif 135 133 QT_END_INCLUDE_NAMESPACE … … 175 173 QSize req_size; 176 174 177 #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)175 #if defined(Q_WS_X11) && defined(QT_NO_EGL) 178 176 GLXPbuffer pbuf; 179 177 GLXContext ctx; … … 196 194 # endif 197 195 #endif 198 #if defined(QT_OPENGL_ES)196 #ifndef QT_NO_EGL 199 197 EGLSurface pbuf; 200 198 QEglContext *ctx; -
trunk/src/opengl/qglpixelbuffer_win.cpp
r651 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) … … 168 168 #endif 169 169 170 #ifndef WGL_ARB_multisample 171 #define WGL_SAMPLE_BUFFERS_ARB 0x2041 172 #define WGL_SAMPLES_ARB 0x2042 173 #endif 174 175 #ifndef GL_SAMPLES_ARB 176 #define GL_SAMPLES_ARB 0x80A9 177 #endif 178 170 179 QGLFormat pfiToQGLFormat(HDC hdc, int pfi); 171 180 … … 227 236 attribs[i++] = TRUE; 228 237 } 229 // sample buffers doesn't work in conjunction with the render_texture extension 230 // so igonre that for now 231 // if (f.sampleBuffers()) { 232 // attribs[i++] = WGL_SAMPLE_BUFFERS_ARB; 233 // attribs[i++] = 1; 234 // attribs[i++] = WGL_SAMPLES_ARB; 235 // attribs[i++] = f.samples() == -1 ? 16 : f.samples(); 236 // } 238 if (f.sampleBuffers()) { 239 attribs[i++] = WGL_SAMPLE_BUFFERS_ARB; 240 attribs[i++] = 1; 241 attribs[i++] = WGL_SAMPLES_ARB; 242 attribs[i++] = f.samples() == -1 ? 16 : f.samples(); 243 } 237 244 attribs[i] = 0; 238 245 } … … 240 247 bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget) 241 248 { 242 QGLWidget dmy; 243 dmy.makeCurrent(); // needed for wglGetProcAddress() to succeed 249 QGLTemporaryContext tempContext; 244 250 245 251 PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = … … 255 261 return false; 256 262 257 dc = GetDC(dmy.winId());263 dc = wglGetCurrentDC(); 258 264 Q_ASSERT(dc); 259 260 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 261 (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); 262 263 if (wglGetExtensionsStringARB) { 264 QString extensions(QLatin1String(wglGetExtensionsStringARB(dc))); 265 has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture")); 265 has_render_texture = false; 266 267 // sample buffers doesn't work in conjunction with the render_texture extension 268 if (!f.sampleBuffers()) { 269 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 270 (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); 271 272 if (wglGetExtensionsStringARB) { 273 QString extensions(QLatin1String(wglGetExtensionsStringARB(dc))); 274 has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture")); 275 } 266 276 } 267 277 … … 285 295 if (num_formats == 0) { 286 296 qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up."); 287 ReleaseDC(dmy.winId(), dc);288 297 return false; 289 298 } … … 298 307 pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 299 308 has_render_texture ? pb_attribs : 0); 300 if (!pbuf) {309 if (!pbuf) { 301 310 // try again without the render_texture extension 302 311 pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0); … … 304 313 if (!pbuf) { 305 314 qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height()); 306 ReleaseDC(dmy.winId(), dc);307 315 return false; 308 316 } 309 317 } 310 318 311 ReleaseDC(dmy.winId(), dc);312 319 dc = wglGetPbufferDCARB(pbuf); 313 320 ctx = wglCreateContext(dc); 314 315 321 if (!dc || !ctx) { 316 322 qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up."); 317 323 return false; 318 324 } 325 326 // Explicitly disable the render_texture extension if we have a 327 // multi-sampled pbuffer context. This seems to be a problem only with 328 // ATI cards if multi-sampling is forced globally in the driver. 329 wglMakeCurrent(dc, ctx); 330 GLint samples = 0; 331 glGetIntegerv(GL_SAMPLES_ARB, &samples); 332 if (has_render_texture && samples != 0) 333 has_render_texture = false; 319 334 320 335 HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0; -
trunk/src/opengl/qglpixelbuffer_x11.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) -
trunk/src/opengl/qglpixmapfilter.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) … … 64 64 65 65 // qpixmapfilter.cpp 66 void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);67 Q Image qt_halfScaled(const QImage &source);66 Q_DECL_IMPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0); 67 Q_DECL_IMPORT QImage qt_halfScaled(const QImage &source); 68 68 69 69 void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const … … 437 437 } 438 438 439 void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,439 Q_DECL_IMPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride, 440 440 quint32 *dest, int dstStride); 441 441 -
trunk/src/opengl/qglpixmapfilter_p.h
r651 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) -
trunk/src/opengl/qglscreen_qws.cpp
r651 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) -
trunk/src/opengl/qglscreen_qws.h
r651 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) -
trunk/src/opengl/qglshaderprogram.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) … … 51 51 QT_BEGIN_NAMESPACE 52 52 53 #if !defined(QT_OPENGL_ES_1 _CL) && !defined(QT_OPENGL_ES_1)53 #if !defined(QT_OPENGL_ES_1) 54 54 55 55 /*! … … 144 144 \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL). 145 145 \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL). 146 \value Geometry Geometry shaders written in the OpenGL Shading 147 Language (GLSL), based on the GL_EXT_geometry_shader4 extension. 146 148 */ 147 149 … … 227 229 if (shaderType == QGLShader::Vertex) 228 230 shader = glCreateShader(GL_VERTEX_SHADER); 231 else if (shaderType == QGLShader::Geometry) 232 shader = glCreateShader(GL_GEOMETRY_SHADER_EXT); 229 233 else 230 234 shader = glCreateShader(GL_FRAGMENT_SHADER); … … 510 514 } 511 515 516 517 518 519 512 520 #undef ctx 513 521 #define ctx programGuard.context() … … 522 530 , inited(false) 523 531 , removingShaders(false) 524 , vertexShader(0) 525 , fragmentShader(0) 532 , geometryVertexCount(64) 533 , geometryInputType(0) 534 , geometryOutputType(0) 526 535 { 527 536 } … … 532 541 bool inited; 533 542 bool removingShaders; 543 544 int geometryVertexCount; 545 GLenum geometryInputType; 546 GLenum geometryOutputType; 547 534 548 QString log; 535 549 QList<QGLShader *> shaders; 536 550 QList<QGLShader *> anonShaders; 537 QGLShader *vertexShader;538 QGLShader *fragmentShader;539 551 540 552 bool hasShader(QGLShader::ShaderType type) const; … … 605 617 d->programGuard.setContext(context); 606 618 } 619 607 620 if (!context) 608 621 return false; … … 832 845 if (!program) 833 846 return false; 847 834 848 GLint value; 835 849 if (d->shaders.isEmpty()) { … … 844 858 return true; 845 859 } 860 861 // Set up the geometry shader parameters 862 if (glProgramParameteriEXT) { 863 foreach (QGLShader *shader, d->shaders) { 864 if (shader->shaderType() & QGLShader::Geometry) { 865 glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, 866 d->geometryInputType); 867 glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, 868 d->geometryOutputType); 869 glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, 870 d->geometryVertexCount); 871 break; 872 } 873 } 874 } 875 846 876 glLinkProgram(program); 847 877 value = 0; … … 1268 1298 Q_UNUSED(d); 1269 1299 if (location != -1) { 1270 GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()}; 1300 GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()), 1301 GLfloat(value.blueF()), GLfloat(value.alphaF())}; 1271 1302 glVertexAttrib4fv(location, values); 1272 1303 } … … 1434 1465 1435 1466 /*! 1467 Sets an array of vertex \a values on the attribute at \a location 1468 in this shader program. The \a stride indicates the number of bytes 1469 between vertices. A default \a stride value of zero indicates that 1470 the vertices are densely packed in \a values. 1471 1472 The \a type indicates the type of elements in the \a values array, 1473 usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize 1474 indicates the number of components per vertex: 1, 2, 3, or 4. 1475 1476 The array will become active when enableAttributeArray() is called 1477 on the \a location. Otherwise the value specified with 1478 setAttributeValue() for \a location will be used. 1479 1480 The setAttributeBuffer() function can be used to set the attribute 1481 array to an offset within a vertex buffer. 1482 1483 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() 1484 \sa disableAttributeArray(), setAttributeBuffer() 1485 \since 4.7 1486 */ 1487 void QGLShaderProgram::setAttributeArray 1488 (int location, GLenum type, const void *values, int tupleSize, int stride) 1489 { 1490 Q_D(QGLShaderProgram); 1491 Q_UNUSED(d); 1492 if (location != -1) { 1493 glVertexAttribPointer(location, tupleSize, type, GL_TRUE, 1494 stride, values); 1495 } 1496 } 1497 1498 /*! 1436 1499 \overload 1437 1500 … … 1516 1579 { 1517 1580 setAttributeArray(attributeLocation(name), values, stride); 1581 } 1582 1583 /*! 1584 \overload 1585 1586 Sets an array of vertex \a values on the attribute called \a name 1587 in this shader program. The \a stride indicates the number of bytes 1588 between vertices. A default \a stride value of zero indicates that 1589 the vertices are densely packed in \a values. 1590 1591 The \a type indicates the type of elements in the \a values array, 1592 usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize 1593 indicates the number of components per vertex: 1, 2, 3, or 4. 1594 1595 The array will become active when enableAttributeArray() is called 1596 on the \a name. Otherwise the value specified with 1597 setAttributeValue() for \a name will be used. 1598 1599 The setAttributeBuffer() function can be used to set the attribute 1600 array to an offset within a vertex buffer. 1601 1602 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() 1603 \sa disableAttributeArray(), setAttributeBuffer() 1604 \since 4.7 1605 */ 1606 void QGLShaderProgram::setAttributeArray 1607 (const char *name, GLenum type, const void *values, int tupleSize, int stride) 1608 { 1609 setAttributeArray(attributeLocation(name), type, values, tupleSize, stride); 1610 } 1611 1612 /*! 1613 Sets an array of vertex values on the attribute at \a location in 1614 this shader program, starting at a specific \a offset in the 1615 currently bound vertex buffer. The \a stride indicates the number 1616 of bytes between vertices. A default \a stride value of zero 1617 indicates that the vertices are densely packed in the value array. 1618 1619 The \a type indicates the type of elements in the vertex value 1620 array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a 1621 tupleSize indicates the number of components per vertex: 1, 2, 3, 1622 or 4. 1623 1624 The array will become active when enableAttributeArray() is called 1625 on the \a location. Otherwise the value specified with 1626 setAttributeValue() for \a location will be used. 1627 1628 \sa setAttributeArray() 1629 \since 4.7 1630 */ 1631 void QGLShaderProgram::setAttributeBuffer 1632 (int location, GLenum type, int offset, int tupleSize, int stride) 1633 { 1634 Q_D(QGLShaderProgram); 1635 Q_UNUSED(d); 1636 if (location != -1) { 1637 glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride, 1638 reinterpret_cast<const void *>(offset)); 1639 } 1640 } 1641 1642 /*! 1643 \overload 1644 1645 Sets an array of vertex values on the attribute called \a name 1646 in this shader program, starting at a specific \a offset in the 1647 currently bound vertex buffer. The \a stride indicates the number 1648 of bytes between vertices. A default \a stride value of zero 1649 indicates that the vertices are densely packed in the value array. 1650 1651 The \a type indicates the type of elements in the vertex value 1652 array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a 1653 tupleSize indicates the number of components per vertex: 1, 2, 3, 1654 or 4. 1655 1656 The array will become active when enableAttributeArray() is called 1657 on the \a name. Otherwise the value specified with 1658 setAttributeValue() for \a name will be used. 1659 1660 \sa setAttributeArray() 1661 \since 4.7 1662 */ 1663 void QGLShaderProgram::setAttributeBuffer 1664 (const char *name, GLenum type, int offset, int tupleSize, int stride) 1665 { 1666 setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride); 1518 1667 } 1519 1668 … … 1885 2034 Q_UNUSED(d); 1886 2035 if (location != -1) { 1887 GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()}; 2036 GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()), 2037 GLfloat(color.blueF()), GLfloat(color.alphaF())}; 1888 2038 glUniform4fv(location, 1, values); 1889 2039 } … … 1914 2064 Q_UNUSED(d); 1915 2065 if (location != -1) { 1916 GLfloat values[4] = { point.x(), point.y()};2066 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; 1917 2067 glUniform2fv(location, 1, values); 1918 2068 } … … 1943 2093 Q_UNUSED(d); 1944 2094 if (location != -1) { 1945 GLfloat values[4] = { point.x(), point.y()};2095 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; 1946 2096 glUniform2fv(location, 1, values); 1947 2097 } … … 1972 2122 Q_UNUSED(d); 1973 2123 if (location != -1) { 1974 GLfloat values[4] = { size.width(), size.width()};2124 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())}; 1975 2125 glUniform2fv(location, 1, values); 1976 2126 } … … 2001 2151 Q_UNUSED(d); 2002 2152 if (location != -1) { 2003 GLfloat values[4] = { size.width(), size.height()};2153 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())}; 2004 2154 glUniform2fv(location, 1, values); 2005 2155 } … … 2315 2465 2316 2466 Sets the uniform variable at \a location in the current context 2467 to a 2x2 matrix \a value. The matrix elements must be specified 2468 in column-major order. 2469 2470 \sa setAttributeValue() 2471 \since 4.7 2472 */ 2473 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2]) 2474 { 2475 Q_D(QGLShaderProgram); 2476 Q_UNUSED(d); 2477 if (location != -1) 2478 glUniformMatrix2fv(location, 1, GL_FALSE, value[0]); 2479 } 2480 2481 /*! 2482 \overload 2483 2484 Sets the uniform variable at \a location in the current context 2485 to a 3x3 matrix \a value. The matrix elements must be specified 2486 in column-major order. 2487 2488 \sa setAttributeValue() 2489 \since 4.7 2490 */ 2491 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3]) 2492 { 2493 Q_D(QGLShaderProgram); 2494 Q_UNUSED(d); 2495 if (location != -1) 2496 glUniformMatrix3fv(location, 1, GL_FALSE, value[0]); 2497 } 2498 2499 /*! 2500 \overload 2501 2502 Sets the uniform variable at \a location in the current context 2317 2503 to a 4x4 matrix \a value. The matrix elements must be specified 2318 2504 in column-major order. … … 2326 2512 if (location != -1) 2327 2513 glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); 2514 } 2515 2516 2517 /*! 2518 \overload 2519 2520 Sets the uniform variable called \a name in the current context 2521 to a 2x2 matrix \a value. The matrix elements must be specified 2522 in column-major order. 2523 2524 \sa setAttributeValue() 2525 \since 4.7 2526 */ 2527 void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2]) 2528 { 2529 setUniformValue(uniformLocation(name), value); 2530 } 2531 2532 /*! 2533 \overload 2534 2535 Sets the uniform variable called \a name in the current context 2536 to a 3x3 matrix \a value. The matrix elements must be specified 2537 in column-major order. 2538 2539 \sa setAttributeValue() 2540 \since 4.7 2541 */ 2542 void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3]) 2543 { 2544 setUniformValue(uniformLocation(name), value); 2328 2545 } 2329 2546 … … 2355 2572 if (location != -1) { 2356 2573 GLfloat mat[3][3] = { 2357 { value.m11(), value.m12(), value.m13()},2358 { value.m21(), value.m22(), value.m23()},2359 { value.m31(), value.m32(), value.m33()}2574 {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())}, 2575 {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())}, 2576 {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())} 2360 2577 }; 2361 2578 glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]); … … 2870 3087 2871 3088 /*! 3089 Returns the hardware limit for how many vertices a geometry shader 3090 can output. 3091 3092 \since 4.7 3093 3094 \sa setGeometryOutputVertexCount() 3095 */ 3096 int QGLShaderProgram::maxGeometryOutputVertices() const 3097 { 3098 GLint n; 3099 glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); 3100 return n; 3101 } 3102 3103 /*! 3104 Sets the maximum number of vertices the current geometry shader 3105 program will produce, if active, to \a count. 3106 3107 \since 4.7 3108 3109 This parameter takes effect the next time the program is linked. 3110 */ 3111 void QGLShaderProgram::setGeometryOutputVertexCount(int count) 3112 { 3113 #ifndef QT_NO_DEBUG 3114 int max = maxGeometryOutputVertices(); 3115 if (count > max) { 3116 qWarning("QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d", 3117 count, max); 3118 } 3119 #endif 3120 d_func()->geometryVertexCount = count; 3121 } 3122 3123 3124 /*! 3125 Returns the maximum number of vertices the current geometry shader 3126 program will produce, if active. 3127 3128 \since 4.7 3129 3130 This parameter takes effect the ntext time the program is linked. 3131 */ 3132 int QGLShaderProgram::geometryOutputVertexCount() const 3133 { 3134 return d_func()->geometryVertexCount; 3135 } 3136 3137 3138 /*! 3139 Sets the input type from \a inputType. 3140 3141 This parameter takes effect the next time the program is linked. 3142 */ 3143 void QGLShaderProgram::setGeometryInputType(GLenum inputType) 3144 { 3145 d_func()->geometryInputType = inputType; 3146 } 3147 3148 3149 /*! 3150 Returns the geometry shader input type, if active. 3151 3152 This parameter takes effect the next time the program is linked. 3153 3154 \since 4.7 3155 */ 3156 3157 GLenum QGLShaderProgram::geometryInputType() const 3158 { 3159 return d_func()->geometryInputType; 3160 } 3161 3162 3163 /*! 3164 Sets the output type from the geometry shader, if active, to 3165 \a outputType. 3166 3167 This parameter takes effect the next time the program is linked. 3168 3169 \since 4.7 3170 */ 3171 void QGLShaderProgram::setGeometryOutputType(GLenum outputType) 3172 { 3173 d_func()->geometryOutputType = outputType; 3174 } 3175 3176 3177 /*! 3178 Returns the geometry shader output type, if active. 3179 3180 This parameter takes effect the next time the program is linked. 3181 3182 \since 4.7 3183 */ 3184 GLenum QGLShaderProgram::geometryOutputType() const 3185 { 3186 return d_func()->geometryOutputType; 3187 } 3188 3189 3190 /*! 2872 3191 Returns true if shader programs written in the OpenGL Shading 2873 3192 Language (GLSL) are supported on this system; false otherwise. … … 2901 3220 } 2902 3221 3222 3223 #undef ctx 3224 #undef context 3225 3226 /*! 3227 Returns true if shader programs of type \a type are supported on 3228 this system; false otherwise. 3229 3230 The \a context is used to resolve the GLSL extensions. 3231 If \a context is null, then QGLContext::currentContext() is used. 3232 3233 \since 4.7 3234 */ 3235 bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context) 3236 { 3237 if (!context) 3238 context = QGLContext::currentContext(); 3239 if (!context) 3240 return false; 3241 3242 if ((type & ~(Geometry | Vertex | Fragment)) || type == 0) 3243 return false; 3244 3245 bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context)); 3246 if (!resolved) 3247 return false; 3248 3249 if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4")) 3250 return false; 3251 3252 return true; 3253 } 3254 3255 3256 2903 3257 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS 2904 3258 /*! \internal */ 3259 void QGLShaderProgram::setAttributeArray 3260 (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride) 3261 { 3262 setAttributeArray(location, GLenum(type), values, tupleSize, stride); 3263 } 3264 3265 /*! \internal */ 3266 void QGLShaderProgram::setAttributeArray 3267 (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride) 3268 { 3269 setAttributeArray(name, GLenum(type), values, tupleSize, stride); 3270 } 3271 3272 /*! \internal */ 3273 void QGLShaderProgram::setAttributeBuffer 3274 (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride) 3275 { 3276 setAttributeBuffer(location, GLenum(type), offset, tupleSize, stride); 3277 } 3278 3279 /*! \internal */ 3280 void QGLShaderProgram::setAttributeBuffer 3281 (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride) 3282 { 3283 setAttributeBuffer(name, GLenum(type), offset, tupleSize, stride); 3284 } 3285 3286 /*! \internal */ 2905 3287 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value) 2906 3288 { … … 2951 3333 #endif 2952 3334 2953 #endif // !defined(QT_OPENGL_ES_1 _CL) && !defined(QT_OPENGL_ES_1)3335 #endif // !defined(QT_OPENGL_ES_1) 2954 3336 2955 3337 QT_END_NAMESPACE -
trunk/src/opengl/qglshaderprogram.h
r651 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) … … 55 55 QT_MODULE(OpenGL) 56 56 57 #if !defined(QT_OPENGL_ES_1 _CL) && !defined(QT_OPENGL_ES_1)57 #if !defined(QT_OPENGL_ES_1) 58 58 59 59 class QGLShaderProgram; … … 67 67 { 68 68 Vertex = 0x0001, 69 Fragment = 0x0002 69 Fragment = 0x0002, 70 Geometry = 0x0004 70 71 }; 71 72 Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) … … 89 90 GLuint shaderId() const; 90 91 92 static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = 0); 93 91 94 private: 92 95 friend class QGLShaderProgram; … … 100 103 101 104 class QGLShaderProgramPrivate; 105 106 #ifndef GL_EXT_geometry_shader4 107 # define GL_LINES_ADJACENCY_EXT 0xA 108 # define GL_LINE_STRIP_ADJACENCY_EXT 0xB 109 # define GL_TRIANGLES_ADJACENCY_EXT 0xC 110 # define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD 111 #endif 112 102 113 103 114 class Q_OPENGL_EXPORT QGLShaderProgram : public QObject … … 128 139 129 140 GLuint programId() const; 141 142 int maxGeometryOutputVertices() const; 143 144 void setGeometryOutputVertexCount(int count); 145 int geometryOutputVertexCount() const; 146 147 void setGeometryInputType(GLenum inputType); 148 GLenum geometryInputType() const; 149 150 void setGeometryOutputType(GLenum outputType); 151 GLenum geometryOutputType() const; 130 152 131 153 void bindAttributeLocation(const char *name, int location); … … 166 188 (int location, const QVector4D *values, int stride = 0); 167 189 void setAttributeArray 190 (int location, GLenum type, const void *values, int tupleSize, int stride = 0); 191 void setAttributeArray 168 192 (const char *name, const GLfloat *values, int tupleSize, int stride = 0); 169 193 void setAttributeArray … … 173 197 void setAttributeArray 174 198 (const char *name, const QVector4D *values, int stride = 0); 199 void setAttributeArray 200 (const char *name, GLenum type, const void *values, int tupleSize, int stride = 0); 201 202 void setAttributeBuffer 203 (int location, GLenum type, int offset, int tupleSize, int stride = 0); 204 void setAttributeBuffer 205 (const char *name, GLenum type, int offset, int tupleSize, int stride = 0); 206 207 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS 208 void setAttributeArray 209 (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0); 210 void setAttributeArray 211 (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0); 212 void setAttributeBuffer 213 (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0); 214 void setAttributeBuffer 215 (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0); 216 #endif 175 217 176 218 void enableAttributeArray(int location); … … 217 259 void setUniformValue(int location, const QMatrix4x3& value); 218 260 void setUniformValue(int location, const QMatrix4x4& value); 261 void setUniformValue(int location, const GLfloat value[2][2]); 262 void setUniformValue(int location, const GLfloat value[3][3]); 219 263 void setUniformValue(int location, const GLfloat value[4][4]); 220 264 void setUniformValue(int location, const QTransform& value); … … 243 287 void setUniformValue(const char *name, const QMatrix4x3& value); 244 288 void setUniformValue(const char *name, const QMatrix4x4& value); 289 void setUniformValue(const char *name, const GLfloat value[2][2]); 290 void setUniformValue(const char *name, const GLfloat value[3][3]); 245 291 void setUniformValue(const char *name, const GLfloat value[4][4]); 246 292 void setUniformValue(const char *name, const QTransform& value); -
trunk/src/opengl/qglwindowsurface_qws.cpp
r651 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) -
trunk/src/opengl/qglwindowsurface_qws_p.h
r651 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) -
trunk/src/opengl/qgraphicsshadereffect.cpp
r651 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) … … 41 41 42 42 #include "qgraphicsshadereffect_p.h" 43 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)43 #if !defined(QT_OPENGL_ES_1) 44 44 #include "qglshaderprogram.h" 45 45 #include "gl2paintengineex/qglcustomshaderstage_p.h" -
trunk/src/opengl/qgraphicsshadereffect_p.h
r651 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) -
trunk/src/opengl/qgraphicssystem_gl.cpp
r651 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) … … 41 41 42 42 #include "qgraphicssystem_gl_p.h" 43 #include <QGraphicsView> 43 44 44 45 #include "private/qpixmap_raster_p.h" … … 48 49 #include <private/qwindowsurface_raster_p.h> 49 50 50 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES)51 #if defined(Q_WS_X11) && !defined(QT_NO_EGL) 51 52 #include "private/qpixmapdata_x11gl_p.h" 52 53 #include "private/qwindowsurface_x11gl_p.h" … … 59 60 QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const 60 61 { 61 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES)62 if (type == QPixmapData::PixmapType && QX11GLPixmapData::hasX11GLPixmaps())63 return new QX11GLPixmapData();64 #endif65 66 62 return new QGLPixmapData(type); 67 63 } … … 77 73 #endif 78 74 79 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) 80 if (QX11GLPixmapData::hasX11GLPixmaps()) 81 return new QX11GLWindowSurface(widget); 75 #if defined(Q_WS_X11) && !defined(QT_NO_EGL) 76 if (m_useX11GL && QX11GLPixmapData::hasX11GLPixmaps()) { 77 // If the widget is a QGraphicsView which will be re-drawing the entire 78 // scene each frame anyway, we should use QGLWindowSurface as this may 79 // provide proper buffer flipping, which should be faster than QX11GL's 80 // blitting approach: 81 QGraphicsView* qgv = qobject_cast<QGraphicsView*>(widget); 82 if (qgv && qgv->viewportUpdateMode() == QGraphicsView::FullViewportUpdate) 83 return new QGLWindowSurface(widget); 84 else 85 return new QX11GLWindowSurface(widget); 86 } 82 87 #endif 83 88 -
trunk/src/opengl/qgraphicssystem_gl_p.h
r651 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) … … 63 63 { 64 64 public: 65 QGLGraphicsSystem( );65 QGLGraphicsSystem(bool useX11GL); 66 66 67 67 QPixmapData *createPixmapData(QPixmapData::PixelType type) const; 68 68 QWindowSurface *createWindowSurface(QWidget *widget) const; 69 private: 70 bool m_useX11GL; 69 71 }; 70 72 -
trunk/src/opengl/qpaintengine_opengl.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) … … 61 61 #include <private/qbezier_p.h> 62 62 #include <qglframebufferobject.h> 63 #include <private/qstatictext_p.h> 63 64 64 65 #include "private/qtessellator_p.h" … … 72 73 #endif 73 74 74 #ifdef QT_OPENGL_ES_1_CL75 #include "qgl_cl_p.h"76 #endif77 78 75 #define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context()); 79 76 … … 83 80 QT_BEGIN_NAMESPACE 84 81 85 extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp82 Q_DECL_IMPORT extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp 86 83 #ifdef QT_MAC_USE_COCOA 87 84 extern void *qt_current_nsopengl_context(); // qgl_mac.mm … … 510 507 ////////// GL program cache: start 511 508 512 typedef struct{509 struct GLProgram { 513 510 int brush; // brush index or mask index 514 511 int mode; // composition mode index 515 512 bool mask; 516 513 GLuint program; 517 } GLProgram;514 }; 518 515 519 516 typedef QMultiHash<const QGLContext *, GLProgram> QGLProgramHash; … … 672 669 , shader_ctx(0) 673 670 , grad_palette(0) 671 , tess_points(0) 674 672 , drawable_texture(0) 675 673 , ref_cleaner(this) … … 781 779 782 780 void composite(const QRectF &rect, const QPoint &maskOffset = QPoint()); 783 void composite(GLuint primitive, const q_vertexType*vertexArray, int vertexCount, const QPoint &maskOffset = QPoint());781 void composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint()); 784 782 785 783 bool createFragmentPrograms(); … … 924 922 stroker.setJoinStyle(cpen.joinStyle()); 925 923 stroker.setMiterLimit(cpen.miterLimit()); 924 stroker.setDashOffset(cpen.dashOffset()); 926 925 927 926 qreal width = cpen.widthF(); … … 1793 1792 QOpenGLTrapezoidToArrayTessellator() : vertices(0), allocated(0), size(0) {} 1794 1793 ~QOpenGLTrapezoidToArrayTessellator() { free(vertices); } 1795 q_vertexType*vertices;1794 GLfloat *vertices; 1796 1795 int allocated; 1797 1796 int size; … … 1814 1813 #endif 1815 1814 allocated = qMax(2*allocated, 512); 1816 vertices = ( q_vertexType *)realloc(vertices, allocated * sizeof(q_vertexType));1815 vertices = (GLfloat *)realloc(vertices, allocated * sizeof(GLfloat)); 1817 1816 } 1818 1817 … … 1820 1819 1821 1820 #ifndef QT_OPENGL_ES 1822 vertices[size++] = f2vt(t.topLeftX);1823 vertices[size++] = f2vt(t.top);1824 vertices[size++] = f2vt(t.topRightX);1825 vertices[size++] = f2vt(t.top);1826 vertices[size++] = f2vt(t.bottomRightX);1827 vertices[size++] = f2vt(t.bottom);1828 vertices[size++] = f2vt(t.bottomLeftX);1829 vertices[size++] = f2vt(t.bottom);1821 vertices[size++] = t.topLeftX; 1822 vertices[size++] = t.top; 1823 vertices[size++] = t.topRightX; 1824 vertices[size++] = t.top; 1825 vertices[size++] = t.bottomRightX; 1826 vertices[size++] = t.bottom; 1827 vertices[size++] = t.bottomLeftX; 1828 vertices[size++] = t.bottom; 1830 1829 #else 1831 1830 // First triangle 1832 vertices[size++] = f2vt(t.topLeftX);1833 vertices[size++] = f2vt(t.top);1834 vertices[size++] = f2vt(t.topRightX);1835 vertices[size++] = f2vt(t.top);1836 vertices[size++] = f2vt(t.bottomRightX);1837 vertices[size++] = f2vt(t.bottom);1831 vertices[size++] = t.topLeftX; 1832 vertices[size++] = t.top; 1833 vertices[size++] = t.topRightX; 1834 vertices[size++] = t.top; 1835 vertices[size++] = t.bottomRightX; 1836 vertices[size++] = t.bottom; 1838 1837 1839 1838 // Second triangle 1840 vertices[size++] = f2vt(t.bottomLeftX);1841 vertices[size++] = f2vt(t.bottom);1842 vertices[size++] = f2vt(t.topLeftX);1843 vertices[size++] = f2vt(t.top);1844 vertices[size++] = f2vt(t.bottomRightX);1845 vertices[size++] = f2vt(t.bottom);1839 vertices[size++] = t.bottomLeftX; 1840 vertices[size++] = t.bottom; 1841 vertices[size++] = t.topLeftX; 1842 vertices[size++] = t.top; 1843 vertices[size++] = t.bottomRightX; 1844 vertices[size++] = t.bottom; 1846 1845 #endif 1847 1846 } … … 1870 1869 composite(geometry_mode, tessellator.vertices, tessellator.size / 2); 1871 1870 } else { 1872 glVertexPointer(2, q_vertexTypeEnum, 0, tessellator.vertices);1871 glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices); 1873 1872 glEnableClientState(GL_VERTEX_ARRAY); 1874 1873 glDrawArrays(geometry_mode, 0, tessellator.size/2); … … 1959 1958 void QOpenGLPaintEnginePrivate::drawVertexArrays() 1960 1959 { 1960 if (tess_points_stops.count() == 0) 1961 return; 1961 1962 glEnableClientState(GL_VERTEX_ARRAY); 1962 1963 glVertexPointer(2, GL_DOUBLE, 0, tess_points.data()); … … 2271 2272 } 2272 2273 2273 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_1_CL)2274 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2) 2274 2275 glClearDepthf(0.0f); 2275 2276 #else … … 2287 2288 2288 2289 // rectangle count * 2 (triangles) * vertex count * component count (Z omitted) 2289 QDataBuffer< q_vertexType> clipVertex(rects.size()*2*3*2);2290 QDataBuffer<GLfloat> clipVertex(rects.size()*2*3*2); 2290 2291 for (int i = 0; i < rects.size(); ++i) { 2291 q_vertexType x = i2vt(rects.at(i).left());2292 q_vertexType w = i2vt(rects.at(i).width());2293 q_vertexType h = i2vt(rects.at(i).height());2294 q_vertexType y = i2vt(rects.at(i).top());2292 GLfloat x = GLfloat(rects.at(i).left()); 2293 GLfloat w = GLfloat(rects.at(i).width()); 2294 GLfloat h = GLfloat(rects.at(i).height()); 2295 GLfloat y = GLfloat(rects.at(i).top()); 2295 2296 2296 2297 // First triangle … … 2320 2321 2321 2322 glEnableClientState(GL_VERTEX_ARRAY); 2322 glVertexPointer(2, q_vertexTypeEnum, 0, clipVertex.data());2323 glVertexPointer(2, GL_FLOAT, 0, clipVertex.data()); 2323 2324 2324 2325 glDrawArrays(GL_TRIANGLES, 0, rects.size()*2*3); … … 3112 3113 } 3113 3114 3114 extern void qt_add_rect_to_array(const QRectF &r, q_vertexType*array);3115 extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType*array);3115 extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); 3116 extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array); 3116 3117 3117 3118 void QGLTrapezoidMaskGenerator::drawMask(const QRect &rect) … … 3144 3145 // clear mask 3145 3146 glBlendFunc(GL_ZERO, GL_ZERO); // clear 3146 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3147 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3147 3148 glEnableClientState(GL_VERTEX_ARRAY); 3148 3149 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); … … 3351 3352 QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate; 3352 3353 3353 float m[3][4] = { { inv_matrix.m11(), inv_matrix.m12(), inv_matrix.m13() },3354 { inv_matrix.m21(), inv_matrix.m22(), inv_matrix.m23() },3355 { inv_matrix.m31(), inv_matrix.m32(), inv_matrix.m33() } };3354 float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) }, 3355 { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) }, 3356 { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } }; 3356 3357 3357 3358 QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top()) … … 3359 3360 3360 3361 // last component needs to be 1.0f to avoid Nvidia bug on linux 3361 float ellipse_offset[4] = { offs.x(), offs.y(), 0.0f, 1.0f };3362 float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f }; 3362 3363 3363 3364 GLfloat vertexArray[4 * 2]; … … 3375 3376 3376 3377 glEnableClientState(GL_VERTEX_ARRAY); 3377 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3378 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3378 3379 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 3379 3380 glDisableClientState(GL_VERTEX_ARRAY); … … 3405 3406 DEBUG_ONCE_STR("QOpenGLPaintEngine::drawRects(): drawing fast rect"); 3406 3407 3407 q_vertexTypevertexArray[10];3408 GLfloat vertexArray[10]; 3408 3409 qt_add_rect_to_array(r, vertexArray); 3409 3410 … … 3426 3427 if (fast_style && has_fast_composition_mode) { 3427 3428 glEnableClientState(GL_VERTEX_ARRAY); 3428 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3429 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3429 3430 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 3430 3431 glDisableClientState(GL_VERTEX_ARRAY); … … 3445 3446 vertexArray[9] = vertexArray[1]; 3446 3447 3447 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3448 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3448 3449 glEnableClientState(GL_VERTEX_ARRAY); 3449 3450 glDrawArrays(GL_LINE_STRIP, 0, 5); … … 3552 3553 } 3553 3554 3554 static void addQuadAsTriangle( q_vertexType *quad, q_vertexType*triangle)3555 static void addQuadAsTriangle(GLfloat *quad, GLfloat *triangle) 3555 3556 { 3556 3557 triangle[0] = quad[0]; … … 3613 3614 3614 3615 if (d->has_fast_pen) { 3615 QVarLengthArray< q_vertexType> vertexArray(6 * pointCount);3616 QVarLengthArray<GLfloat> vertexArray(6 * pointCount); 3616 3617 3617 3618 glMatrixMode(GL_MODELVIEW); … … 3623 3624 QPointF mapped = d->matrix.map(points[i]); 3624 3625 3625 qreal xf = qRound(mapped.x()); 3626 qreal yf = qRound(mapped.y()); 3627 3628 q_vertexType x = f2vt(xf); 3629 q_vertexType y = f2vt(yf); 3626 GLfloat x = GLfloat(qRound(mapped.x())); 3627 GLfloat y = GLfloat(qRound(mapped.y())); 3630 3628 3631 3629 vertexArray[j++] = x; 3632 vertexArray[j++] = y - f2vt(0.5);3633 3634 vertexArray[j++] = x + f2vt(1.5);3635 vertexArray[j++] = y + f2vt(1.0);3630 vertexArray[j++] = y - 0.5f; 3631 3632 vertexArray[j++] = x + 1.5f; 3633 vertexArray[j++] = y + 1.0f; 3636 3634 3637 3635 vertexArray[j++] = x; 3638 vertexArray[j++] = y + f2vt(1.0);3636 vertexArray[j++] = y + 1.0f; 3639 3637 } 3640 3638 3641 3639 glEnableClientState(GL_VERTEX_ARRAY); 3642 3640 3643 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData());3641 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); 3644 3642 glDrawArrays(GL_TRIANGLES, 0, pointCount*3); 3645 3643 … … 3658 3656 else { 3659 3657 Q_ASSERT(sizeof(QPointF) == 8); 3660 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3658 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3661 3659 } 3662 3660 … … 3726 3724 } 3727 3725 3728 q_vertexType endCap = f2vt(d->cpen.capStyle() == Qt::FlatCap ? 0 : 0.5);3726 GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f; 3729 3727 if (useRects) { 3730 QVarLengthArray< q_vertexType> vertexArray(12 * lineCount);3731 3732 q_vertexTypequad[8];3728 QVarLengthArray<GLfloat> vertexArray(12 * lineCount); 3729 3730 GLfloat quad[8]; 3733 3731 for (int i = 0; i < lineCount; ++i) { 3734 q_vertexType x1 = f2vt(lines[i].x1());3735 q_vertexType x2 = f2vt(lines[i].x2());3736 q_vertexType y1 = f2vt(lines[i].y1());3737 q_vertexType y2 = f2vt(lines[i].y2());3732 GLfloat x1 = lines[i].x1(); 3733 GLfloat x2 = lines[i].x2(); 3734 GLfloat y1 = lines[i].y1(); 3735 GLfloat y2 = lines[i].y2(); 3738 3736 3739 3737 if (x1 == x2) { … … 3741 3739 qSwap(y1, y2); 3742 3740 3743 quad[0] = x1 - f2vt(0.5);3741 quad[0] = x1 - 0.5f; 3744 3742 quad[1] = y1 - endCap; 3745 3743 3746 quad[2] = x1 + f2vt(0.5);3744 quad[2] = x1 + 0.5f; 3747 3745 quad[3] = y1 - endCap; 3748 3746 3749 quad[4] = x1 + f2vt(0.5);3747 quad[4] = x1 + 0.5f; 3750 3748 quad[5] = y2 + endCap; 3751 3749 3752 quad[6] = x1 - f2vt(0.5);3750 quad[6] = x1 - 0.5f; 3753 3751 quad[7] = y2 + endCap; 3754 3752 } else { … … 3757 3755 3758 3756 quad[0] = x1 - endCap; 3759 quad[1] = y1 + f2vt(0.5);3757 quad[1] = y1 + 0.5f; 3760 3758 3761 3759 quad[2] = x1 - endCap; 3762 quad[3] = y1 - f2vt(0.5);3760 quad[3] = y1 - 0.5f; 3763 3761 3764 3762 quad[4] = x2 + endCap; 3765 quad[5] = y1 - f2vt(0.5);3763 quad[5] = y1 - 0.5f; 3766 3764 3767 3765 quad[6] = x2 + endCap; 3768 quad[7] = y1 + f2vt(0.5);3766 quad[7] = y1 + 0.5f; 3769 3767 } 3770 3768 … … 3774 3772 glEnableClientState(GL_VERTEX_ARRAY); 3775 3773 3776 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData());3774 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); 3777 3775 glDrawArrays(GL_TRIANGLES, 0, lineCount*6); 3778 3776 3779 3777 glDisableClientState(GL_VERTEX_ARRAY); 3780 3778 } else { 3781 QVarLengthArray< q_vertexType> vertexArray(4 * lineCount);3779 QVarLengthArray<GLfloat> vertexArray(4 * lineCount); 3782 3780 for (int i = 0; i < lineCount; ++i) { 3783 3781 const QPointF a = lines[i].p1(); 3784 vertexArray[4*i] = f2vt(lines[i].x1());3785 vertexArray[4*i+1] = f2vt(lines[i].y1());3786 vertexArray[4*i+2] = f2vt(lines[i].x2());3787 vertexArray[4*i+3] = f2vt(lines[i].y2());3782 vertexArray[4*i] = lines[i].x1(); 3783 vertexArray[4*i+1] = lines[i].y1(); 3784 vertexArray[4*i+2] = lines[i].x2(); 3785 vertexArray[4*i+3] = lines[i].y2(); 3788 3786 } 3789 3787 3790 3788 glEnableClientState(GL_VERTEX_ARRAY); 3791 3789 3792 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData());3790 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); 3793 3791 glDrawArrays(GL_LINES, 0, lineCount*2); 3794 3792 3795 glVertexPointer(2, q_vertexTypeEnum, 4*sizeof(q_vertexType), vertexArray.constData() + 2);3793 glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2); 3796 3794 glDrawArrays(GL_POINTS, 0, lineCount); 3797 3795 … … 3880 3878 else { 3881 3879 Q_ASSERT(sizeof(QPointF) == 8); 3882 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);3880 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 3883 3881 } 3884 3882 … … 3899 3897 if (d->has_fast_pen && !d->high_quality_antialiasing) { 3900 3898 d->setGradientOps(d->cpen.brush(), bounds); 3901 QVarLengthArray< q_vertexType> vertexArray(pointCount*2 + 2);3902 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray.constData());3899 QVarLengthArray<GLfloat> vertexArray(pointCount*2 + 2); 3900 glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData()); 3903 3901 int i; 3904 3902 for (i=0; i<pointCount; ++i) { 3905 vertexArray[i*2] = f2vt(points[i].x());3906 vertexArray[i*2+1] = f2vt(points[i].y());3903 vertexArray[i*2] = points[i].x(); 3904 vertexArray[i*2+1] = points[i].y(); 3907 3905 } 3908 3906 … … 3959 3957 } 3960 3958 3961 externbool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp3959 Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp 3962 3960 3963 3961 void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_cache) … … 4080 4078 case QPainterPath::MoveToElement: 4081 4079 if (i != 0) { 4082 glVertexPointer(2, q_vertexTypeEnum, 0, tess_points.data());4080 glVertexPointer(2, GL_FLOAT, 0, tess_points.data()); 4083 4081 glDrawArrays(GL_LINE_STRIP, 0, tess_points.size()); 4084 4082 tess_points.reset(); … … 4130 4128 } // end of switch 4131 4129 } 4132 glVertexPointer(2, q_vertexTypeEnum, 0, tess_points.data());4130 glVertexPointer(2, GL_FLOAT, 0, tess_points.data()); 4133 4131 glDrawArrays(GL_LINE_STRIP, 0, tess_points.size()); 4134 4132 glDisableClientState(GL_VERTEX_ARRAY); … … 4397 4395 } 4398 4396 4399 q_vertexTypevertexArray[4*2];4400 q_vertexTypetexCoordArray[4*2];4397 GLfloat vertexArray[4*2]; 4398 GLfloat texCoordArray[4*2]; 4401 4399 4402 4400 double offset_x = offset.x() / pm.width(); … … 4407 4405 tc_w + offset_x, tc_h + offset_y, texCoordArray); 4408 4406 4409 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);4410 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);4407 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 4408 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); 4411 4409 4412 4410 glEnableClientState(GL_VERTEX_ARRAY); … … 4489 4487 } 4490 4488 4491 q_vertexTypevertexArray[4*2];4492 q_vertexTypetexCoordArray[4*2];4489 GLfloat vertexArray[4*2]; 4490 GLfloat texCoordArray[4*2]; 4493 4491 4494 4492 qt_add_rect_to_array(r, vertexArray); 4495 4493 qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray); 4496 4494 4497 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);4498 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);4495 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 4496 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); 4499 4497 4500 4498 glEnableClientState(GL_VERTEX_ARRAY); … … 4561 4559 ~QGLGlyphCache(); 4562 4560 QGLGlyphCoord *lookup(QFontEngine *, glyph_t); 4563 void cacheGlyphs(QGLContext *, const QTextItemInt &, const QVarLengthArray<glyph_t> &);4561 void cacheGlyphs(QGLContext *, QFontEngine *, glyph_t *glyphs, int numGlyphs); 4564 4562 void cleanCache(); 4565 4563 void allocTexture(int width, int height, GLuint texture); … … 4713 4711 #endif 4714 4712 4715 void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,4716 const QVarLengthArray<glyph_t> &glyphs)4713 void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine, 4714 glyph_t *glyphs, int numGlyphs) 4717 4715 { 4718 4716 QGLContextHash::const_iterator dev_it = qt_context_cache.constFind(context); … … 4738 4736 // qDebug() << "new context" << context << font_cache; 4739 4737 qt_context_cache.insert(context, font_cache); 4740 if (context->isValid() && context->device()->devType() == QInternal::Widget) { 4741 QWidget *widget = static_cast<QWidget *>(context->device()); 4742 connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*))); 4738 if (context->isValid()) { 4739 if (context->device()->devType() == QInternal::Widget) { 4740 QWidget *widget = static_cast<QWidget *>(context->device()); 4741 connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*))); 4742 } 4743 4743 connect(QGLSignalProxy::instance(), 4744 4744 SIGNAL(aboutToDestroyContext(const QGLContext*)), … … 4750 4750 Q_ASSERT(font_cache != 0); 4751 4751 4752 QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind( ti.fontEngine);4752 QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine); 4753 4753 QGLGlyphHash *cache = 0; 4754 4754 if (cache_it == font_cache->constEnd()) { 4755 4755 cache = new QGLGlyphHash; 4756 font_cache->insert( ti.fontEngine, cache);4757 connect( ti.fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*)));4756 font_cache->insert(fontEngine, cache); 4757 connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*))); 4758 4758 } else { 4759 4759 cache = cache_it.value(); … … 4762 4762 4763 4763 quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32) 4764 | reinterpret_cast<quint64>( ti.fontEngine);4764 | reinterpret_cast<quint64>(fontEngine); 4765 4765 QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key); 4766 4766 QGLFontTexture *font_tex; … … 4768 4768 GLuint font_texture; 4769 4769 glGenTextures(1, &font_texture); 4770 GLint tex_height = qt_next_power_of_two(qRound( ti.ascent.toReal() + ti.descent.toReal())+2);4770 GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); 4771 4771 GLint tex_width = qt_next_power_of_two(tex_height*30); // ### 4772 4772 GLint max_tex_size; … … 4790 4790 } 4791 4791 4792 for (int i=0; i< glyphs.size(); ++i) {4792 for (int i=0; i< numGlyphs; ++i) { 4793 4793 QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]); 4794 4794 if (it == cache->constEnd()) { 4795 4795 // render new glyph and put it in the cache 4796 glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);4796 glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]); 4797 4797 int glyph_width = qRound(metrics.width.toReal())+2; 4798 int glyph_height = qRound( ti.ascent.toReal() + ti.descent.toReal())+2;4798 int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2; 4799 4799 4800 4800 if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) { 4801 int strip_height = qt_next_power_of_two(qRound( ti.ascent.toReal() + ti.descent.toReal())+2);4801 int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2); 4802 4802 font_tex->x_offset = x_margin; 4803 4803 font_tex->y_offset += strip_height; … … 4832 4832 } 4833 4833 4834 QImage glyph_im( ti.fontEngine->alphaMapForGlyph(glyphs[i]));4834 QImage glyph_im(fontEngine->alphaMapForGlyph(glyphs[i])); 4835 4835 glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8); 4836 4836 glyph_width = glyph_im.width(); … … 4912 4912 } 4913 4913 4914 void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) 4915 { 4916 Q_D(QOpenGLPaintEngine); 4917 4918 d->flushDrawQueue(); 4919 4920 // make sure the glyphs we want to draw are in the cache 4921 qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine(), textItem->glyphs, 4922 textItem->numGlyphs); 4923 4924 d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops 4925 qt_glColor4ubv(d->pen_color); 4926 glEnable(GL_TEXTURE_2D); 4927 4928 #ifdef Q_WS_QWS 4929 // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want 4930 // text rendering to update the alpha in the window surface. 4931 // XXX: This may not be needed as this behavior does seem to be caused by driver bug 4932 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); 4933 #endif 4934 4935 // do the actual drawing 4936 GLfloat vertexArray[4*2]; 4937 GLfloat texCoordArray[4*2]; 4938 4939 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 4940 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); 4941 4942 glEnableClientState(GL_VERTEX_ARRAY); 4943 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 4944 bool antialias = !(textItem->fontEngine()->fontDef.styleStrategy & QFont::NoAntialias) 4945 && (d->matrix.type() > QTransform::TxTranslate); 4946 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST); 4947 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST); 4948 4949 for (int i=0; i< textItem->numGlyphs; ++i) { 4950 QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine(), textItem->glyphs[i]); 4951 4952 // we don't cache glyphs with no width/height 4953 if (!g) 4954 continue; 4955 4956 qreal x1, x2, y1, y2; 4957 x1 = g->x; 4958 y1 = g->y; 4959 x2 = x1 + g->width; 4960 y2 = y1 + g->height; 4961 4962 QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(), 4963 (textItem->glyphPositions[i].y + g->y_offset).toReal()); 4964 4965 qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray); 4966 qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray); 4967 4968 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 4969 } 4970 4971 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 4972 glDisableClientState(GL_VERTEX_ARRAY); 4973 4974 glDisable(GL_TEXTURE_2D); 4975 4976 #ifdef Q_WS_QWS 4977 // XXX: This may not be needed as this behavior does seem to be caused by driver bug 4978 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 4979 #endif 4980 4981 } 4982 4914 4983 void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) 4915 4984 { … … 4926 4995 } 4927 4996 4928 d->flushDrawQueue();4929 4930 4997 // add the glyphs used to the glyph texture cache 4931 4998 QVarLengthArray<QFixedPoint> positions; … … 4934 5001 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 4935 5002 4936 // make sure the glyphs we want to draw are in the cache 4937 qt_glyph_cache()->cacheGlyphs(d->device->context(), ti, glyphs); 4938 4939 d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops 4940 qt_glColor4ubv(d->pen_color); 4941 glEnable(GL_TEXTURE_2D); 4942 4943 #ifdef Q_WS_QWS 4944 // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want 4945 // text rendering to update the alpha in the window surface. 4946 // XXX: This may not be needed as this behavior does seem to be caused by driver bug 4947 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); 4948 #endif 4949 4950 // do the actual drawing 4951 q_vertexType vertexArray[4*2]; 4952 q_vertexType texCoordArray[4*2]; 4953 4954 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); 4955 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); 4956 4957 glEnableClientState(GL_VERTEX_ARRAY); 4958 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 4959 bool antialias = !(ti.fontEngine->fontDef.styleStrategy & QFont::NoAntialias) 4960 && (d->matrix.type() > QTransform::TxTranslate); 4961 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST); 4962 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST); 4963 4964 for (int i=0; i< glyphs.size(); ++i) { 4965 QGLGlyphCoord *g = qt_glyph_cache()->lookup(ti.fontEngine, glyphs[i]); 4966 4967 // we don't cache glyphs with no width/height 4968 if (!g) 4969 continue; 4970 4971 qreal x1, x2, y1, y2; 4972 x1 = g->x; 4973 y1 = g->y; 4974 x2 = x1 + g->width; 4975 y2 = y1 + g->height; 4976 4977 QPointF logical_pos((positions[i].x - g->x_offset).toReal(), 4978 (positions[i].y + g->y_offset).toReal()); 4979 4980 qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray); 4981 qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray); 4982 4983 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 4984 } 4985 4986 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 4987 glDisableClientState(GL_VERTEX_ARRAY); 4988 4989 glDisable(GL_TEXTURE_2D); 4990 4991 #ifdef Q_WS_QWS 4992 // XXX: This may not be needed as this behavior does seem to be caused by driver bug 4993 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 4994 #endif 5003 { 5004 QStaticTextItem staticTextItem; 5005 staticTextItem.chars = const_cast<QChar *>(ti.chars); 5006 staticTextItem.setFontEngine(ti.fontEngine); 5007 staticTextItem.glyphs = glyphs.data(); 5008 staticTextItem.numChars = ti.num_chars; 5009 staticTextItem.numGlyphs = glyphs.size(); 5010 staticTextItem.glyphPositions = positions.data(); 5011 drawStaticTextItem(&staticTextItem); 5012 } 5013 4995 5014 } 4996 5015 … … 5166 5185 Q_UNUSED(maskOffset); 5167 5186 #else 5168 q_vertexTypevertexArray[8];5187 GLfloat vertexArray[8]; 5169 5188 qt_add_rect_to_array(rect, vertexArray); 5170 5189 … … 5174 5193 5175 5194 5176 void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType*vertexArray, int vertexCount, const QPoint &maskOffset)5195 void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset) 5177 5196 { 5178 5197 #ifdef QT_OPENGL_ES … … 5197 5216 5198 5217 for (int i = 0; i < vertexCount; ++i) { 5199 qreal x = v t2f(vertexArray[2 * i]);5200 qreal y = v t2f(vertexArray[2 * i + 1]);5218 qreal x = vertexArray[2 * i]; 5219 qreal y = vertexArray[2 * i + 1]; 5201 5220 5202 5221 qreal tx, ty; … … 5257 5276 5258 5277 glEnableClientState(GL_VERTEX_ARRAY); 5259 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);5278 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 5260 5279 glEnable(GL_FRAGMENT_PROGRAM_ARB); 5261 5280 GLuint program = qt_gl_program_cache()->getProgram(device->context(), -
trunk/src/opengl/qpaintengine_opengl_p.h
r651 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) … … 134 134 Qt::ImageConversionFlags conversionFlags); 135 135 void drawTextItem(const QPointF &p, const QTextItem &ti); 136 void drawStaticTextItem(QStaticTextItem *staticTextItem); 136 137 137 138 void drawEllipse(const QRectF &rect); -
trunk/src/opengl/qpixmapdata_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) … … 368 368 369 369 void QGLPixmapData::fromImage(const QImage &image, 370 Qt::ImageConversionFlags /*flags*/)370 Qt::ImageConversionFlags flags) 371 371 { 372 372 if (image.size() == QSize(w, h)) … … 382 382 format = QImage::Format_RGB16; 383 383 384 if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) 384 if (image.hasAlphaChannel() 385 && ((flags & Qt::NoOpaqueDetection) 386 || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels())) 385 387 format = QImage::Format_ARGB32_Premultiplied;; 386 388 … … 471 473 void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) 472 474 { 473 if (data->classId() != QPixmapData::OpenGLClass ) {475 if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) { 474 476 QPixmapData::copy(data, rect); 475 477 return; 476 478 } 477 479 478 // can be optimized to do a framebuffer blit or similar ... 479 QPixmapData::copy(data, rect); 480 const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data); 481 if (other->m_renderFbo) { 482 QGLShareContextScope ctx(qt_gl_share_widget()->context()); 483 484 resize(rect.width(), rect.height()); 485 m_hasAlpha = other->m_hasAlpha; 486 ensureCreated(); 487 488 if (!ctx->d_ptr->fbo) 489 glGenFramebuffers(1, &ctx->d_ptr->fbo); 490 491 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); 492 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 493 GL_TEXTURE_2D, m_texture.id, 0); 494 495 if (!other->m_renderFbo->isBound()) 496 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle()); 497 498 glDisable(GL_SCISSOR_TEST); 499 if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2) 500 static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState(); 501 502 glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), 503 0, 0, w, h, 504 GL_COLOR_BUFFER_BIT, 505 GL_NEAREST); 506 507 glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); 508 } else { 509 QPixmapData::copy(data, rect); 510 } 480 511 } 481 512 … … 622 653 } 623 654 624 bool QGLPixmapData::useFramebufferObjects() 655 bool QGLPixmapData::useFramebufferObjects() const 625 656 { 626 657 return QGLFramebufferObject::hasOpenGLFramebufferObjects() 627 658 && QGLFramebufferObject::hasOpenGLFramebufferBlit() 628 && qt_gl_preferGL2Engine(); 659 && qt_gl_preferGL2Engine() 660 && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps 629 661 } 630 662 … … 708 740 } 709 741 710 extern int qt_defaultDpiX();711 extern int qt_defaultDpiY();742 Q_DECL_IMPORT extern int qt_defaultDpiX(); 743 Q_DECL_IMPORT extern int qt_defaultDpiY(); 712 744 713 745 int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -
trunk/src/opengl/qpixmapdata_gl_p.h
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) … … 97 97 98 98 99 class Q GLPixmapData : public QPixmapData99 class Q_OPENGL_EXPORT QGLPixmapData : public QPixmapData 100 100 { 101 101 public: … … 146 146 QSize size() const { return QSize(w, h); } 147 147 148 static bool useFramebufferObjects();148 bool useFramebufferObjects() const; 149 149 150 150 QImage fillImage(const QColor &color) const; … … 169 169 170 170 friend class QGLPixmapGLPaintDevice; 171 friend class QMeeGoPixmapData; 172 friend class QMeeGoLivePixmapData; 171 173 }; 172 174 -
trunk/src/opengl/qpixmapdata_x11gl_egl.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) … … 42 42 #include <QDebug> 43 43 44 #include <private/qgl_p.h> 45 #include <private/qegl_p.h> 46 #include <private/qeglproperties_p.h> 47 48 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) 49 #include <private/qpaintengineex_opengl2_p.h> 44 #include <QtGui/private/qt_x11_p.h> 45 #include <QtGui/private/qegl_p.h> 46 #include <QtGui/private/qeglproperties_p.h> 47 #include <QtGui/private/qeglcontext_p.h> 48 49 #if !defined(QT_OPENGL_ES_1) 50 #include <QtOpenGL/private/qpaintengineex_opengl2_p.h> 50 51 #endif 51 52 52 53 #ifndef QT_OPENGL_ES_2 53 #include <private/qpaintengine_opengl_p.h> 54 #endif 54 #include <QtOpenGL/private/qpaintengine_opengl_p.h> 55 #endif 56 57 #include <QtOpenGL/private/qgl_p.h> 58 #include <QtOpenGL/private/qgl_egl_p.h> 55 59 56 60 #include "qpixmapdata_x11gl_p.h" … … 58 62 QT_BEGIN_NAMESPACE 59 63 60 extern EGLConfig qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly); // in qgl_x11egl.cpp 61 extern bool qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly); // in qgl_x11egl.cpp 62 63 // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need 64 // different contexts: 65 static EGLContext qPixmapARGBSharedEglContext = EGL_NO_CONTEXT; 66 static EGLContext qPixmapRGBSharedEglContext = EGL_NO_CONTEXT; 67 68 bool QX11GLPixmapData::hasX11GLPixmaps() 69 { 70 static bool checkedForX11Pixmaps = false; 71 static bool haveX11Pixmaps = false; 72 73 if (checkedForX11Pixmaps) 74 return haveX11Pixmaps; 75 76 checkedForX11Pixmaps = true; 77 78 QX11PixmapData *argbPixmapData = 0; 79 QX11PixmapData *rgbPixmapData = 0; 80 do { 81 if (qgetenv("QT_USE_X11GL_PIXMAPS").isEmpty()) 82 break; 83 84 // Check we actually have EGL configs which support pixmaps 85 EGLConfig argbConfig = qt_chooseEGLConfigForPixmap(true, false); 86 EGLConfig rgbConfig = qt_chooseEGLConfigForPixmap(false, false); 87 88 if (argbConfig == 0 || rgbConfig == 0) 89 break; 90 91 // Create the shared contexts: 92 eglBindAPI(EGL_OPENGL_ES_API); 93 EGLint contextAttribs[] = { 94 #if defined(QT_OPENGL_ES_2) 95 EGL_CONTEXT_CLIENT_VERSION, 2, 96 #endif 97 EGL_NONE 98 }; 99 qPixmapARGBSharedEglContext = eglCreateContext(QEglContext::display(), 100 argbConfig, 0, contextAttribs); 101 102 if (argbConfig == rgbConfig) { 103 // If the configs are the same, we can re-use the same context. 104 qPixmapRGBSharedEglContext = qPixmapARGBSharedEglContext; 105 } else { 106 qPixmapRGBSharedEglContext = eglCreateContext(QEglContext::display(), 107 rgbConfig, 0, contextAttribs); 108 } 109 110 argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); 111 argbPixmapData->resize(100, 100); 112 argbPixmapData->fill(Qt::transparent); // Force ARGB 113 114 if (!qt_createEGLSurfaceForPixmap(argbPixmapData, false)) 115 break; 116 117 haveX11Pixmaps = eglMakeCurrent(QEglContext::display(), 118 (EGLSurface)argbPixmapData->gl_surface, 119 (EGLSurface)argbPixmapData->gl_surface, 120 qPixmapARGBSharedEglContext); 121 if (!haveX11Pixmaps) { 122 EGLint err = eglGetError(); 123 qWarning() << "Unable to make pixmap config current:" << err << QEglContext::errorString(err); 124 break; 125 } 126 127 // If the ARGB & RGB configs are the same, we don't need to check RGB too 128 if (haveX11Pixmaps && (argbConfig != rgbConfig)) { 129 rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); 130 rgbPixmapData->resize(100, 100); 64 65 class QX11GLSharedContexts 66 { 67 public: 68 QX11GLSharedContexts() 69 : rgbContext(0) 70 , argbContext(0) 71 , sharedQGLContext(0) 72 , sharePixmap(0) 73 { 74 EGLint rgbConfigId; 75 EGLint argbConfigId; 76 77 do { 78 EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable); 79 EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, 80 QEgl::Renderable | QEgl::Translucent); 81 82 eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId); 83 eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId); 84 85 rgbContext = new QEglContext; 86 rgbContext->setConfig(rgbConfig); 87 rgbContext->createContext(); 88 89 if (!rgbContext->isValid()) 90 break; 91 92 // If the RGB & ARGB configs are the same, use the same egl context for both: 93 if (rgbConfig == argbConfig) 94 argbContext = rgbContext; 95 96 // Otherwise, create a separate context to be used for ARGB pixmaps: 97 if (!argbContext) { 98 argbContext = new QEglContext; 99 argbContext->setConfig(argbConfig); 100 bool success = argbContext->createContext(rgbContext); 101 if (!success) { 102 qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared"); 103 success = argbContext->createContext(); 104 if (!success) 105 argbContext = rgbContext; // Might work, worth a shot at least. 106 } 107 } 108 109 if (!argbContext->isValid()) 110 break; 111 112 // Create the pixmap which will be used to create the egl surface for the share QGLContext 113 QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); 114 rgbPixmapData->resize(8, 8); 131 115 rgbPixmapData->fill(Qt::red); 132 133 // Try to actually create an EGL pixmap surface 134 if (!qt_createEGLSurfaceForPixmap(rgbPixmapData, false)) 135 break; 136 137 haveX11Pixmaps = eglMakeCurrent(QEglContext::display(), 138 (EGLSurface)rgbPixmapData->gl_surface, 139 (EGLSurface)rgbPixmapData->gl_surface, 140 qPixmapRGBSharedEglContext); 141 if (!haveX11Pixmaps) { 142 EGLint err = eglGetError(); 143 qWarning() << "Unable to make pixmap config current:" << err << QEglContext::errorString(err); 116 sharePixmap = new QPixmap(rgbPixmapData); 117 EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig); 118 rgbPixmapData->gl_surface = (void*)sharePixmapSurface; 119 120 // Create the actual QGLContext which will be used for sharing 121 sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat()); 122 sharedQGLContext->d_func()->eglContext = rgbContext; 123 sharedQGLContext->d_func()->eglSurface = sharePixmapSurface; 124 sharedQGLContext->d_func()->valid = true; 125 qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig); 126 127 128 valid = rgbContext->makeCurrent(sharePixmapSurface); 129 130 // If the ARGB & RGB configs are different, check ARGB works too: 131 if (argbConfig != rgbConfig) { 132 QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); 133 argbPixmapData->resize(8, 8); 134 argbPixmapData->fill(Qt::transparent); // Force ARGB 135 QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope 136 EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig); 137 valid = argbContext->makeCurrent(argbPixmapSurface); 138 argbContext->doneCurrent(); 139 eglDestroySurface(QEgl::display(), argbPixmapSurface); 140 argbPixmapData->gl_surface = 0; 141 } 142 143 if (!valid) { 144 qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString(); 144 145 break; 145 146 } 147 148 // The pixmap surface destruction hooks are installed by QGLTextureCache, so we 149 // must make sure this is instanciated: 150 QGLTextureCache::instance(); 151 } while(0); 152 153 if (!valid) 154 cleanup(); 155 else 156 qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId); 157 158 } 159 160 ~QX11GLSharedContexts() { 161 cleanup(); 162 } 163 164 void cleanup() { 165 if (sharedQGLContext) { 166 delete sharedQGLContext; 167 sharedQGLContext = 0; 146 168 } 147 } while (0); 148 149 if (qPixmapARGBSharedEglContext || qPixmapRGBSharedEglContext) { 150 eglMakeCurrent(QEglContext::display(), 151 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 152 } 153 154 if (argbPixmapData) { 155 if (argbPixmapData->gl_surface) 156 QGLContextPrivate::destroyGlSurfaceForPixmap(argbPixmapData); 157 delete argbPixmapData; 158 argbPixmapData = 0; 159 } 160 if (rgbPixmapData) { 161 if (rgbPixmapData->gl_surface) 162 QGLContextPrivate::destroyGlSurfaceForPixmap(rgbPixmapData); 163 delete rgbPixmapData; 164 rgbPixmapData = 0; 165 } 166 167 if (!haveX11Pixmaps) { 168 // Clean up the context(s) if we can't use X11GL pixmaps 169 if (qPixmapARGBSharedEglContext != EGL_NO_CONTEXT) 170 eglDestroyContext(QEglContext::display(), qPixmapARGBSharedEglContext); 171 172 if (qPixmapRGBSharedEglContext != qPixmapARGBSharedEglContext && 173 qPixmapRGBSharedEglContext != EGL_NO_CONTEXT) 174 { 175 eglDestroyContext(QEglContext::display(), qPixmapRGBSharedEglContext); 169 if (argbContext && argbContext != rgbContext) 170 delete argbContext; 171 argbContext = 0; 172 173 if (rgbContext) { 174 delete rgbContext; 175 rgbContext = 0; 176 176 } 177 qPixmapRGBSharedEglContext = EGL_NO_CONTEXT; 178 qPixmapARGBSharedEglContext = EGL_NO_CONTEXT; 179 } 180 181 if (haveX11Pixmaps) 182 qDebug("QX11GLPixmapData is supported"); 183 else 184 qDebug("QX11GLPixmapData is *NOT* being used"); 185 186 return haveX11Pixmaps; 177 178 // Deleting the QPixmap will fire the pixmap destruction cleanup hooks which in turn 179 // will destroy the egl surface: 180 if (sharePixmap) { 181 delete sharePixmap; 182 sharePixmap = 0; 183 } 184 } 185 186 bool isValid() { return valid;} 187 188 // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need 189 // different contexts: 190 QEglContext *rgbContext; 191 QEglContext *argbContext; 192 193 // The share context wraps the rgbContext and is used as the master of the context share 194 // group. As all other contexts will have the same egl context (or a shared one if rgb != argb) 195 // all QGLContexts will actually be sharing and can be in the same context group. 196 QGLContext *sharedQGLContext; 197 private: 198 QPixmap *sharePixmap; 199 bool valid; 200 }; 201 202 static void qt_cleanup_x11gl_share_contexts(); 203 204 Q_GLOBAL_STATIC_WITH_INITIALIZER(QX11GLSharedContexts, qt_x11gl_share_contexts, 205 { 206 qAddPostRoutine(qt_cleanup_x11gl_share_contexts); 207 }) 208 209 static void qt_cleanup_x11gl_share_contexts() 210 { 211 qt_x11gl_share_contexts()->cleanup(); 212 } 213 214 215 QX11GLSharedContexts* QX11GLPixmapData::sharedContexts() 216 { 217 return qt_x11gl_share_contexts(); 218 } 219 220 bool QX11GLPixmapData::hasX11GLPixmaps() 221 { 222 static bool checkedForX11GLPixmaps = false; 223 static bool haveX11GLPixmaps = false; 224 225 if (checkedForX11GLPixmaps) 226 return haveX11GLPixmaps; 227 228 haveX11GLPixmaps = qt_x11gl_share_contexts()->isValid(); 229 checkedForX11GLPixmaps = true; 230 231 return haveX11GLPixmaps; 187 232 } 188 233 … … 195 240 QX11GLPixmapData::~QX11GLPixmapData() 196 241 { 197 } 198 199 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) 242 if (ctx) 243 delete ctx; 244 } 245 246 247 void QX11GLPixmapData::fill(const QColor &color) 248 { 249 if (ctx) { 250 ctx->makeCurrent(); 251 glFinish(); 252 eglWaitClient(); 253 } 254 255 QX11PixmapData::fill(color); 256 XSync(X11->display, False); 257 258 if (ctx) { 259 ctx->makeCurrent(); 260 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 261 } 262 } 263 264 void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect) 265 { 266 if (ctx) { 267 ctx->makeCurrent(); 268 glFinish(); 269 eglWaitClient(); 270 } 271 272 QX11PixmapData::copy(data, rect); 273 XSync(X11->display, False); 274 275 if (ctx) { 276 ctx->makeCurrent(); 277 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 278 } 279 } 280 281 bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect) 282 { 283 if (ctx) { 284 ctx->makeCurrent(); 285 glFinish(); 286 eglWaitClient(); 287 } 288 289 bool success = QX11PixmapData::scroll(dx, dy, rect); 290 XSync(X11->display, False); 291 292 if (ctx) { 293 ctx->makeCurrent(); 294 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 295 } 296 297 return success; 298 } 299 300 #if !defined(QT_OPENGL_ES_1) 200 301 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine) 201 302 #endif … … 211 312 if (!ctx) { 212 313 ctx = new QGLContext(glFormat()); 213 if (ctx->d_func()->eglContext == 0) 214 ctx->d_func()->eglContext = new QEglContext(); 215 ctx->d_func()->eglContext->setApi(QEgl::OpenGL); 216 ctx->d_func()->eglContext->setContext(hasAlphaChannel() ? qPixmapARGBSharedEglContext 217 : qPixmapRGBSharedEglContext); 314 Q_ASSERT(ctx->d_func()->eglContext == 0); 315 ctx->d_func()->eglContext = hasAlphaChannel() ? sharedContexts()->argbContext : sharedContexts()->rgbContext; 316 317 // While we use a separate QGLContext for each pixmap, the underlying QEglContext is 318 // the same. So we must use a "fake" QGLContext and fool the texture cache into thinking 319 // each pixmap's QGLContext is sharing with this central one. The only place this is 320 // going to fail is where we the underlying EGL RGB and ARGB contexts aren't sharing. 321 ctx->d_func()->sharing = true; 322 QGLContextGroup::addShare(ctx, sharedContexts()->sharedQGLContext); 323 324 // Update the glFormat for the QGLContext: 325 qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config()); 218 326 } 219 327 220 328 QPaintEngine* engine; 221 329 222 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)330 #if defined(QT_OPENGL_ES_1) 223 331 engine = qt_gl_pixmap_engine(); 224 332 #elif defined(QT_OPENGL_ES_2) … … 237 345 qWarning("Pixmap paint engine already active"); 238 346 239 #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)347 #if defined(QT_OPENGL_ES_1) 240 348 engine = new QOpenGLPaintEngine; 241 349 #elif defined(QT_OPENGL_ES_2) … … 258 366 { 259 367 // qDebug("QX11GLPixmapData::beginPaint()"); 368 // TODO: Check to see if the surface is renderable 260 369 if ((EGLSurface)gl_surface == EGL_NO_SURFACE) { 261 qt_createEGLSurfaceForPixmap(this, false); 262 ctx->d_func()->eglSurface = (EGLSurface)gl_surface; 263 ctx->d_func()->valid = true; // ;-) 370 QPixmap tmpPixmap(this); 371 EGLConfig cfg = ctx->d_func()->eglContext->config(); 372 Q_ASSERT(cfg != QEGL_NO_CONFIG); 373 374 // qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID)); 375 EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg); 376 if (surface == EGL_NO_SURFACE) { 377 qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString(); 378 return; 379 } 380 gl_surface = (void*)surface; 381 ctx->d_func()->eglSurface = surface; 382 ctx->d_func()->valid = true; 264 383 } 265 384 QGLPaintDevice::beginPaint(); 266 385 } 267 386 268 void QX11GLPixmapData::endPaint()269 {270 glFinish();271 QGLPaintDevice::endPaint();272 }273 274 387 QGLContext* QX11GLPixmapData::context() const 275 388 { -
trunk/src/opengl/qpixmapdata_x11gl_p.h
r651 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) … … 60 60 #include <qgl.h> 61 61 62 #ifndef QT_NO_EGL 63 #include <QtGui/private/qeglcontext_p.h> 64 #endif 65 62 66 QT_BEGIN_NAMESPACE 67 68 class QX11GLSharedContexts; 63 69 64 70 class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice … … 68 74 virtual ~QX11GLPixmapData(); 69 75 76 // Re-implemented from QX11PixmapData: 77 void fill(const QColor &color); 78 void copy(const QPixmapData *data, const QRect &rect); 79 bool scroll(int dx, int dy, const QRect &rect); 80 70 81 // Re-implemented from QGLPaintDevice 71 82 QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine 72 83 void beginPaint(); 73 void endPaint();74 84 QGLContext* context() const; 75 85 QSize size() const; … … 77 87 static bool hasX11GLPixmaps(); 78 88 static QGLFormat glFormat(); 89 static QX11GLSharedContexts* sharedContexts(); 90 79 91 private: 80 92 mutable QGLContext* ctx; -
trunk/src/opengl/qwindowsurface_gl.cpp
r651 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) … … 83 83 #endif 84 84 85 #ifdef QT_OPENGL_ES_1_CL 86 #include "qgl_cl_p.h" 87 #endif 88 89 #ifdef QT_OPENGL_ES 90 #include <private/qegl_p.h> 85 #ifndef QT_NO_EGL 86 #include <private/qeglcontext_p.h> 91 87 #endif 92 88 … … 99 95 extern Q_GUI_EXPORT bool qt_win_owndc_required; 100 96 #endif 101 QGLGraphicsSystem::QGLGraphicsSystem( )102 : QGraphicsSystem() 97 QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) 98 : QGraphicsSystem(), m_useX11GL(useX11GL) 103 99 { 104 100 #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) … … 195 191 if (!initializing && !widget && !cleanedUp) { 196 192 initializing = true; 197 widget = new QGLWidget; 198 // We dont need this internal widget to appear in QApplication::topLevelWidgets() 193 194 widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer)); 195 widget->resize(1, 1); 196 197 // We don't need this internal widget to appear in QApplication::topLevelWidgets() 199 198 if (QWidgetPrivate::allWidgets) 200 199 QWidgetPrivate::allWidgets->remove(widget); … … 204 203 } 205 204 205 // destroys the share widget and prevents recreation 206 206 void cleanup() { 207 207 QGLWidget *w = widget; … … 211 211 } 212 212 213 // destroys the share widget, but allows it to be recreated later on 214 void destroy() { 215 if (cleanedUp) 216 return; 217 218 QGLWidget *w = widget; 219 220 // prevent potential recursions 221 cleanedUp = true; 222 widget = 0; 223 delete w; 224 cleanedUp = false; 225 } 226 213 227 static bool cleanedUp; 214 228 … … 238 252 } 239 253 254 void qt_destroy_gl_share_widget() 255 { 256 _qt_gl_share_widget()->destroy(); 257 } 240 258 241 259 struct QGLWindowSurfacePrivate … … 250 268 int destructive_swap_buffers : 1; 251 269 int geometry_updated : 1; 270 int did_paint : 1; 252 271 253 272 QGLContext *ctx; … … 257 276 QRegion paintedRegion; 258 277 QSize size; 278 279 QSize textureSize; 259 280 260 281 QList<QImage> buffers; … … 264 285 265 286 QGLFormat QGLWindowSurface::surfaceFormat; 287 QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior = QGLWindowSurface::AutomaticSwap; 266 288 267 289 void QGLWindowSurfaceGLPaintDevice::endPaint() … … 299 321 d_ptr->fbo = 0; 300 322 d_ptr->ctx = 0; 323 d_ptr->tex_id = 0; 301 324 #if defined (QT_OPENGL_ES_2) 302 325 d_ptr->tried_fbo = true; … … 310 333 d_ptr->q_ptr = this; 311 334 d_ptr->geometry_updated = false; 335 d_ptr->did_paint = false; 312 336 } 313 337 … … 328 352 void QGLWindowSurface::deleted(QObject *object) 329 353 { 330 // Make sure that the fbo is destroyed before destroying its context.331 delete d_ptr->fbo;332 d_ptr->fbo = 0;333 334 354 QWidget *widget = qobject_cast<QWidget *>(object); 335 355 if (widget) { 356 if (widget == window()) { 357 // Make sure that the fbo is destroyed before destroying its context. 358 delete d_ptr->fbo; 359 d_ptr->fbo = 0; 360 } 361 336 362 QWidgetPrivate *widgetPrivate = widget->d_func(); 337 363 if (widgetPrivate->extraData()) { … … 355 381 return; 356 382 357 QGLContext *ctx = new QGLContext(surfaceFormat, widget); 383 QGLContext *ctx = NULL; 384 385 // For translucent top-level widgets we need alpha in the format. 386 if (widget->testAttribute(Qt::WA_TranslucentBackground)) { 387 QGLFormat modFormat(surfaceFormat); 388 modFormat.setSampleBuffers(false); 389 modFormat.setSamples(0); 390 modFormat.setAlpha(true); 391 ctx = new QGLContext(modFormat, widget); 392 } else 393 ctx = new QGLContext(surfaceFormat, widget); 394 358 395 ctx->create(qt_gl_share_widget()->context()); 359 396 360 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) 361 // Create the EGL surface to draw into. QGLContext::chooseContext() 362 // does not do this for X11/EGL, but does do it for other platforms. 363 // This probably belongs in qgl_x11egl.cpp. 364 QGLContextPrivate *ctxpriv = ctx->d_func(); 365 ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(widget); 366 if (ctxpriv->eglSurface == EGL_NO_SURFACE) { 367 qWarning() << "hijackWindow() could not create EGL surface"; 368 } 369 qDebug("QGLWindowSurface - using EGLConfig %d", reinterpret_cast<int>(ctxpriv->eglContext->config())); 397 #ifndef QT_NO_EGL 398 static bool checkedForNOKSwapRegion = false; 399 static bool haveNOKSwapRegion = false; 400 401 if (!checkedForNOKSwapRegion) { 402 haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2"); 403 checkedForNOKSwapRegion = true; 404 405 if (haveNOKSwapRegion) 406 qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates."; 407 } 408 409 if (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED && 410 ! haveNOKSwapRegion) 411 setPartialUpdateSupport(false); // Force full-screen updates 412 else 413 setPartialUpdateSupport(true); 370 414 #endif 371 415 … … 398 442 QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext); 399 443 ctx->makeCurrent(); 444 445 Q_ASSERT(d_ptr->fbo); 400 446 return d_ptr->fbo; 401 447 } … … 405 451 void QGLWindowSurface::beginPaint(const QRegion &) 406 452 { 453 if (!context()) 454 return; 455 456 int clearFlags = 0; 457 458 if (context()->d_func()->workaround_needsFullClearOnEveryFrame) 459 clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; 460 else if (context()->format().alpha()) 461 clearFlags = GL_COLOR_BUFFER_BIT; 462 463 if (clearFlags) { 464 glClearColor(0.0, 0.0, 0.0, 0.0); 465 glClear(clearFlags); 466 } 467 468 d_ptr->did_paint = true; 407 469 } 408 470 … … 415 477 } 416 478 479 static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect) 480 { 481 glDisable(GL_DEPTH_TEST); 482 glDisable(GL_SCISSOR_TEST); 483 glDisable(GL_BLEND); 484 485 glViewport(0, 0, viewport.width(), viewport.height()); 486 487 QGLShaderProgram *blitProgram = 488 QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); 489 blitProgram->bind(); 490 blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); 491 492 // The shader manager's blit program does not multiply the 493 // vertices by the pmv matrix, so we need to do the effect 494 // of the orthographic projection here ourselves. 495 QRectF r; 496 qreal w = viewport.width(); 497 qreal h = viewport.height(); 498 r.setLeft((targetRect.left() / w) * 2.0f - 1.0f); 499 if (targetRect.right() == (viewport.width() - 1)) 500 r.setRight(1.0f); 501 else 502 r.setRight((targetRect.right() / w) * 2.0f - 1.0f); 503 r.setBottom((targetRect.top() / h) * 2.0f - 1.0f); 504 if (targetRect.bottom() == (viewport.height() - 1)) 505 r.setTop(1.0f); 506 else 507 r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f); 508 509 drawTexture(r, texture, texSize, sourceRect); 510 } 511 512 417 513 void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) 418 514 { 419 if (context() && widget != window()) {420 qWarning("No native child widget support in GL window surface without FBOs or pixel buffers");421 return;422 }423 424 515 //### Find out why d_ptr->geometry_updated isn't always false. 425 516 // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either … … 428 519 return; 429 520 521 // did_paint is set to true in ::beginPaint. ::beginPaint means that we 522 // at least cleared the background (= painted something). In EGL API it's a 523 // mistake to call swapBuffers if nothing was painted unless 524 // EGL_BUFFER_PRESERVED is set. This check protects the flush func from 525 // being executed if it's for nothing. 526 if (!hasPartialUpdateSupport() && !d_ptr->did_paint) 527 return; 528 430 529 QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); 431 530 Q_ASSERT(parent); … … 444 543 const GLenum target = GL_TEXTURE_2D; 445 544 Q_UNUSED(target); 545 546 if (QGLWindowSurface::swapBehavior == QGLWindowSurface::KillSwap) 547 return; 446 548 447 549 if (context()) { … … 492 594 } 493 595 #endif 596 bool doingPartialUpdate = false; 597 if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap) 598 doingPartialUpdate = hasPartialUpdateSupport() && br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2; 599 else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysFullSwap) 600 doingPartialUpdate = false; 601 else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap) 602 doingPartialUpdate = hasPartialUpdateSupport(); 603 604 QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext); 605 if (widget != window()) { 606 if (initializeOffscreenTexture(window()->size())) 607 qWarning() << "QGLWindowSurface: Flushing to native child widget, may lead to significant performance loss"; 608 glBindTexture(target, d_ptr->tex_id); 609 610 const uint bottom = window()->height() - (br.y() + br.height()); 611 glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); 612 613 glBindTexture(target, 0); 614 615 ctx->makeCurrent(); 616 if (doingPartialUpdate) 617 blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), rect, br); 618 else 619 blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), parent->rect(), parent->rect().translated(offset + wOffset)); 620 } 621 622 if (doingPartialUpdate) 623 ctx->d_func()->swapRegion(br); 624 else 625 ctx->swapBuffers(); 626 494 627 d_ptr->paintedRegion = QRegion(); 495 context()->swapBuffers();496 628 } else { 497 629 glFlush(); … … 534 666 535 667 if (window() == parent || d_ptr->fbo->format().samples() <= 1) { 536 // glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); 668 if (ctx->d_ptr->current_fbo != 0) 669 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); 670 537 671 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); 538 672 … … 567 701 qgl_fbo_pool()->release(temp); 568 702 } 703 704 ctx->d_ptr->current_fbo = 0; 569 705 } 570 706 #if !defined(QT_OPENGL_ES_2) … … 613 749 Q_UNUSED(target); 614 750 615 GLuint texture = d_ptr->fbo->texture();616 617 glDisable(GL_DEPTH_TEST);618 619 751 if (d_ptr->fbo->isBound()) 620 752 d_ptr->fbo->release(); 621 753 622 glViewport(0, 0, size.width(), size.height()); 623 624 QGLShaderProgram *blitProgram = 625 QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); 626 blitProgram->bind(); 627 blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); 628 629 // The shader manager's blit program does not multiply the 630 // vertices by the pmv matrix, so we need to do the effect 631 // of the orthographic projection here ourselves. 632 QRectF r; 633 qreal w = size.width() ? size.width() : 1.0f; 634 qreal h = size.height() ? size.height() : 1.0f; 635 r.setLeft((rect.left() / w) * 2.0f - 1.0f); 636 if (rect.right() == (size.width() - 1)) 637 r.setRight(1.0f); 638 else 639 r.setRight((rect.right() / w) * 2.0f - 1.0f); 640 r.setBottom((rect.top() / h) * 2.0f - 1.0f); 641 if (rect.bottom() == (size.height() - 1)) 642 r.setTop(1.0f); 643 else 644 r.setTop((rect.bottom() / w) * 2.0f - 1.0f); 645 646 drawTexture(r, texture, window()->size(), br); 754 blitTexture(ctx, d_ptr->fbo->texture(), size, window()->size(), rect, br); 647 755 } 648 756 #endif … … 652 760 else 653 761 glFlush(); 762 763 d_ptr->did_paint = false; 654 764 } 655 765 … … 667 777 d_ptr->geometry_updated = false; 668 778 669 670 779 QRect rect = geometry(); 671 780 hijackWindow(window()); … … 688 797 if (d_ptr->ctx) { 689 798 #ifndef QT_OPENGL_ES_2 690 if (d_ptr->destructive_swap_buffers) { 691 glBindTexture(target, d_ptr->tex_id); 692 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 693 glBindTexture(target, 0); 694 } 799 if (d_ptr->destructive_swap_buffers) 800 initializeOffscreenTexture(rect.size()); 695 801 #endif 696 802 return; … … 772 878 773 879 #ifndef QT_OPENGL_ES_2 774 if (d_ptr->destructive_swap_buffers) { 775 glGenTextures(1, &d_ptr->tex_id); 776 glBindTexture(target, d_ptr->tex_id); 777 glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 778 779 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 780 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 781 glBindTexture(target, 0); 782 } 880 if (d_ptr->destructive_swap_buffers) 881 initializeOffscreenTexture(rect.size()); 783 882 #endif 784 883 … … 786 885 d_ptr->ctx = ctx; 787 886 d_ptr->ctx->d_ptr->internal_context = true; 887 } 888 889 bool QGLWindowSurface::initializeOffscreenTexture(const QSize &size) 890 { 891 if (size == d_ptr->textureSize) 892 return false; 893 894 glGenTextures(1, &d_ptr->tex_id); 895 glBindTexture(GL_TEXTURE_2D, d_ptr->tex_id); 896 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 897 898 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 899 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 900 glBindTexture(GL_TEXTURE_2D, 0); 901 902 d_ptr->textureSize = size; 903 return true; 788 904 } 789 905 … … 839 955 } 840 956 841 const q_vertexType tx1 = f2vt(src.left());842 const q_vertexType tx2 = f2vt(src.right());843 const q_vertexType ty1 = f2vt(src.top());844 const q_vertexType ty2 = f2vt(src.bottom());845 846 q_vertexTypetexCoordArray[4*2] = {957 const GLfloat tx1 = src.left(); 958 const GLfloat tx2 = src.right(); 959 const GLfloat ty1 = src.top(); 960 const GLfloat ty2 = src.bottom(); 961 962 GLfloat texCoordArray[4*2] = { 847 963 tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1 848 964 }; 849 965 850 q_vertexTypevertexArray[4*2];851 extern void qt_add_rect_to_array(const QRectF &r, q_vertexType*array); // qpaintengine_opengl.cpp966 GLfloat vertexArray[4*2]; 967 extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); // qpaintengine_opengl.cpp 852 968 qt_add_rect_to_array(rect, vertexArray); 853 969 854 970 #if !defined(QT_OPENGL_ES_2) 855 glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);856 glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);971 glVertexPointer(2, GL_FLOAT, 0, vertexArray); 972 glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); 857 973 858 974 glBindTexture(target, tex_id); -
trunk/src/opengl/qwindowsurface_gl_p.h
r651 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) … … 67 67 struct QGLWindowSurfacePrivate; 68 68 69 Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget(); 70 Q_OPENGL_EXPORT void qt_destroy_gl_share_widget(); 71 69 72 class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice 70 73 { … … 78 81 }; 79 82 80 class Q GLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice83 class Q_OPENGL_EXPORT QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice 81 84 { 82 85 Q_OBJECT … … 100 103 static QGLFormat surfaceFormat; 101 104 105 enum SwapMode { AutomaticSwap, AlwaysFullSwap, AlwaysPartialSwap, KillSwap }; 106 static SwapMode swapBehavior; 107 102 108 private slots: 103 109 void deleted(QObject *object); … … 105 111 private: 106 112 void hijackWindow(QWidget *widget); 113 bool initializeOffscreenTexture(const QSize &size); 107 114 108 115 QGLWindowSurfacePrivate *d_ptr; -
trunk/src/opengl/qwindowsurface_x11gl.cpp
r651 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) … … 52 52 53 53 QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window) 54 : QWindowSurface(window), m_ GC(0), m_window(window)54 : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window) 55 55 { 56 56 } … … 58 58 QX11GLWindowSurface::~QX11GLWindowSurface() 59 59 { 60 if (m_GC) 61 XFree(m_GC); 60 if (m_windowGC) 61 XFree(m_windowGC); 62 if (m_pixmapGC) 63 XFree(m_pixmapGC); 62 64 } 63 65 … … 71 73 void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset) 72 74 { 73 // qDebug("QX11GLWindowSurface::flush()"); 74 QTime startTime = QTime::currentTime(); 75 // We don't need to know the widget which initiated the flush. Instead we just use the offset 76 // to translate the widgetRegion: 77 Q_UNUSED(widget); 78 75 79 if (m_backBuffer.isNull()) { 76 qDebug("Q HarmattanWindowSurface::flush() - backBuffer is null, not flushing anything");80 qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything"); 77 81 return; 78 82 } 79 83 80 QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft(); 81 QRegion windowRegion(widgetRegion); 82 QRect boundingRect = widgetRegion.boundingRect(); 83 if (!widgetOffset.isNull()) 84 windowRegion.translate(-widgetOffset); 85 QRect windowBoundingRect = windowRegion.boundingRect(); 84 Q_ASSERT(window()->size() != m_backBuffer.size()); 85 86 // Wait for all GL rendering to the back buffer pixmap to complete before trying to 87 // copy it to the window. We do this by making sure the pixmap's context is current 88 // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to 89 // block, just that "All rendering calls...are guaranteed to be executed before native 90 // rendering calls". This makes it potentially less expensive than glFinish. 91 QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context(); 92 if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) 93 ctx->makeCurrent(); 94 eglWaitClient(); 95 96 if (m_windowGC == 0) { 97 XGCValues attribs; 98 attribs.graphics_exposures = False; 99 m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs); 100 } 86 101 87 102 int rectCount; 88 XRectangle *rects = (XRectangle *)qt_getClipRects(wi ndowRegion, rectCount);103 XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount); 89 104 if (rectCount <= 0) 90 105 return; 91 // qDebug() << "XSetClipRectangles"; 92 // for (int i = 0; i < num; ++i) 93 // qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height; 94 95 if (m_GC == 0) { 96 m_GC = XCreateGC(X11->display, m_window->handle(), 0, 0); 97 XSetGraphicsExposures(X11->display, m_GC, False); 98 } 99 100 XSetClipRectangles(X11->display, m_GC, 0, 0, rects, rectCount, YXBanded); 101 XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_GC, 102 boundingRect.x() + offset.x(), boundingRect.y() + offset.y(), 103 boundingRect.width(), boundingRect.height(), 104 windowBoundingRect.x(), windowBoundingRect.y()); 106 107 XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded); 108 109 QRect dirtyRect = widgetRegion.boundingRect().translated(-offset); 110 XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC, 111 dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), 112 dirtyRect.x(), dirtyRect.y()); 113 114 // Make sure the blit of the update from the back buffer to the window completes 115 // before allowing rendering to start again to the back buffer. Otherwise the GPU 116 // might start rendering to the back buffer again while the blit takes place. 117 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 105 118 } 106 119 … … 108 121 { 109 122 if (rect.width() > m_backBuffer.size().width() || rect.height() > m_backBuffer.size().height()) { 123 QX11GLPixmapData *pd = new QX11GLPixmapData; 110 124 QSize newSize = rect.size(); 111 // QSize newSize(1024,512);112 qDebug() << "QX11GLWindowSurface::setGeometry() - creating a pixmap of size" << newSize;113 QX11GLPixmapData *pd = new QX11GLPixmapData;114 125 pd->resize(newSize.width(), newSize.height()); 115 126 m_backBuffer = QPixmap(pd); 116 } 117 118 // if (gc) 119 // XFreeGC(X11->display, gc); 120 // gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0); 121 // XSetGraphicsExposures(X11->display, gc, False); 127 if (window()->testAttribute(Qt::WA_TranslucentBackground)) 128 m_backBuffer.fill(Qt::transparent); 129 if (m_pixmapGC) { 130 XFreeGC(X11->display, m_pixmapGC); 131 m_pixmapGC = 0; 132 } 133 } 134 122 135 QWindowSurface::setGeometry(rect); 123 136 } … … 125 138 bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy) 126 139 { 127 Q_UNUSED(area); 128 Q_UNUSED(dx); 129 Q_UNUSED(dy); 130 return false; 131 } 132 133 /* 134 void QX11GLWindowSurface::beginPaint(const QRegion ®ion) 135 { 136 } 137 138 void QX11GLWindowSurface::endPaint(const QRegion ®ion) 139 { 140 } 141 142 QImage *QX11GLWindowSurface::buffer(const QWidget *widget) 143 { 144 } 145 */ 140 if (m_backBuffer.isNull()) 141 return false; 142 143 Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class); 144 145 // Make sure all GL rendering is complete before starting the scroll operation: 146 QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context(); 147 if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) 148 ctx->makeCurrent(); 149 eglWaitClient(); 150 151 if (!m_pixmapGC) 152 m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); 153 154 foreach (const QRect& rect, area.rects()) { 155 XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC, 156 rect.x(), rect.y(), rect.width(), rect.height(), 157 rect.x()+dx, rect.y()+dy); 158 } 159 160 // Make sure the scroll operation is complete before allowing GL rendering to resume 161 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 162 163 return true; 164 } 165 166 167 QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const 168 { 169 if (!widget || m_backBuffer.isNull()) 170 return QPixmap(); 171 172 QRect srcRect; 173 174 // make sure the rect is inside the widget & clip to widget's rect 175 if (!rect.isEmpty()) 176 srcRect = rect & widget->rect(); 177 else 178 srcRect = widget->rect(); 179 180 if (srcRect.isEmpty()) 181 return QPixmap(); 182 183 // If it's a child widget we have to translate the coordinates 184 if (widget != window()) 185 srcRect.translate(widget->mapTo(window(), QPoint(0, 0))); 186 187 QPixmap::x11SetDefaultScreen(widget->x11Info().screen()); 188 189 QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType); 190 pmd->resize(srcRect.width(), srcRect.height()); 191 QPixmap px(pmd); 192 193 GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); 194 195 // Make sure all GL rendering is complete before copying the window 196 QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context(); 197 if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) 198 ctx->makeCurrent(); 199 eglWaitClient(); 200 201 // Copy srcRect from the backing store to the new pixmap 202 XSetGraphicsExposures(X11->display, tmpGc, False); 203 XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc, 204 srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0); 205 XFreeGC(X11->display, tmpGc); 206 207 // Wait until the copy has finised before allowing more rendering into the back buffer 208 eglWaitNative(EGL_CORE_NATIVE_ENGINE); 209 210 return px; 211 } 146 212 147 213 QT_END_NAMESPACE -
trunk/src/opengl/qwindowsurface_x11gl_p.h
r651 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) … … 69 69 void setGeometry(const QRect &rect); 70 70 bool scroll(const QRegion &area, int dx, int dy); 71 QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; 71 72 72 73 private: 73 GC m_GC; 74 GC m_windowGC; 75 GC m_pixmapGC; 74 76 QPixmap m_backBuffer; 75 77 QWidget *m_window; -
trunk/src/opengl/util/fragmentprograms_p.h
r651 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) -
trunk/src/opengl/util/generator.cpp
r651 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) … … 288 288 out << "/****************************************************************************\n" 289 289 "**\n" 290 "** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).\n"290 "** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).\n" 291 291 "** All rights reserved.\n" 292 292 "** Contact: Nokia Corporation (qt-info@nokia.com)\n" -
trunk/src/opengl/util/glsl_to_include.sh
r651 r846 2 2 ############################################################################# 3 3 ## 4 ## Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).4 ## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 5 5 ## All rights reserved. 6 6 ## Contact: Nokia Corporation (qt-info@nokia.com)
Note:
See TracChangeset
for help on using the changeset viewer.