diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 244 |
1 files changed, 132 insertions, 112 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4d22646..75c6d0a 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -47,6 +47,8 @@ namespace uirenderer { // TODO: This should be set in properties #define ALPHA_THRESHOLD (0x7f / PANEL_BIT_DEPTH) +#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST) + /////////////////////////////////////////////////////////////////////////////// // Globals /////////////////////////////////////////////////////////////////////////////// @@ -101,12 +103,6 @@ static const Blender gBlendsSwap[] = { { SkXfermode::kScreen_Mode, GL_ONE_MINUS_DST_COLOR, GL_ONE } }; -static const GLenum gTextureUnits[] = { - GL_TEXTURE0, - GL_TEXTURE1, - GL_TEXTURE2 -}; - /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// @@ -131,8 +127,6 @@ OpenGLRenderer::~OpenGLRenderer() { /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setViewport(int width, int height) { - glDisable(GL_DITHER); - glViewport(0, 0, width, height); mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); mWidth = width; @@ -141,7 +135,11 @@ void OpenGLRenderer::setViewport(int width, int height) { mFirstSnapshot->height = height; mFirstSnapshot->viewport.set(0, 0, width, height); - mDirtyClip = false; + glDisable(GL_DITHER); + glEnable(GL_SCISSOR_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + glEnableVertexAttribArray(Program::kBindingPosition); } void OpenGLRenderer::prepare(bool opaque) { @@ -154,17 +152,15 @@ void OpenGLRenderer::prepareDirty(float left, float top, float right, float bott mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSnapshot->fbo = getTargetFbo(); - mSaveCount = 1; glViewport(0, 0, mWidth, mHeight); + mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top); - glEnable(GL_SCISSOR_TEST); - glScissor(left, mSnapshot->height - bottom, right - left, bottom - top); mSnapshot->setClip(left, top, right, bottom); + mDirtyClip = false; if (!opaque) { - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } } @@ -198,20 +194,22 @@ void OpenGLRenderer::interrupt() { } } mCaches.unbindMeshBuffer(); + mCaches.unbindIndicesBuffer(); + mCaches.resetVertexPointers(); + mCaches.disbaleTexCoordsVertexArray(); } void OpenGLRenderer::resume() { sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_SCISSOR_TEST); dirtyClip(); - glDisable(GL_DITHER); - + mCaches.activeTexture(0); glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); mCaches.blend = true; glEnable(GL_BLEND); @@ -451,7 +449,7 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, return false; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Layer* layer = mCaches.layerCache.get(bounds.getWidth(), bounds.getHeight()); if (!layer) { return false; @@ -552,9 +550,8 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> sna #endif // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering - glScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f, + mCaches.setScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f, clip.getWidth() + 2.0f, clip.getHeight() + 2.0f); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); dirtyClip(); @@ -594,7 +591,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { mCaches.unbindMeshBuffer(); - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); // When the layer is stored in an FBO, we can save a bit of fillrate by // drawing only the dirty region @@ -613,6 +610,11 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { } if (fboLayer) { + // Note: No need to use glDiscardFramebufferEXT() since we never + // create/compose layers that are not on screen with this + // code path + // See LayerRenderer::destroyLayer(Layer*) + // Detach the texture from the FBO glBindFramebuffer(GL_FRAMEBUFFER, current->fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); @@ -665,10 +667,10 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f); - layer->setFilter(GL_NEAREST, GL_NEAREST); + layer->setFilter(GL_NEAREST); setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true); } else { - layer->setFilter(GL_LINEAR, GL_LINEAR); + layer->setFilter(GL_LINEAR); setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom); } setupDrawTextureTransformUniforms(layer->getTexTransform()); @@ -702,9 +704,9 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f); } - layer->setFilter(GL_NEAREST, GL_NEAREST, true); + layer->setFilter(GL_NEAREST, true); } else { - layer->setFilter(GL_LINEAR, GL_LINEAR, true); + layer->setFilter(GL_LINEAR, true); } drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(), @@ -760,13 +762,13 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f); - layer->setFilter(GL_NEAREST, GL_NEAREST); + layer->setFilter(GL_NEAREST); setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true); } else { - layer->setFilter(GL_LINEAR, GL_LINEAR); + layer->setFilter(GL_LINEAR); setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom); } - setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]); + setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]); for (size_t i = 0; i < count; i++) { const android::Rect* r = &rects[i]; @@ -795,7 +797,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, NULL); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS @@ -904,10 +905,8 @@ void OpenGLRenderer::clearLayerRegions() { setupDrawProgram(); setupDrawPureColorUniforms(); setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true); + setupDrawVertices(&mesh[0].position[0]); - mCaches.unbindMeshBuffer(); - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gVertexStride, &mesh[0].position[0]); glDrawArrays(GL_TRIANGLES, 0, count * 6); glEnable(GL_SCISSOR_TEST); @@ -941,7 +940,11 @@ void OpenGLRenderer::skew(float sx, float sy) { } void OpenGLRenderer::setMatrix(SkMatrix* matrix) { - mSnapshot->transform->load(*matrix); + if (matrix) { + mSnapshot->transform->load(*matrix); + } else { + mSnapshot->transform->loadIdentity(); + } } void OpenGLRenderer::getMatrix(SkMatrix* matrix) { @@ -962,7 +965,10 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { void OpenGLRenderer::setScissorFromClip() { Rect clip(*mSnapshot->clipRect); clip.snapToPixelBoundaries(); - glScissor(clip.left, mSnapshot->height - clip.bottom, clip.getWidth(), clip.getHeight()); + + mCaches.setScissor(clip.left, mSnapshot->height - clip.bottom, + clip.getWidth(), clip.getHeight()); + mDirtyClip = false; } @@ -1008,7 +1014,6 @@ void OpenGLRenderer::setupDraw(bool clear) { mColorA = mColorR = mColorG = mColorB = 0.0f; mTextureUnit = 0; mTrackDirtyRegions = true; - mTexCoordsSlot = -1; } void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { @@ -1020,6 +1025,10 @@ void OpenGLRenderer::setupDrawWithExternalTexture() { mDescription.hasExternalTexture = true; } +void OpenGLRenderer::setupDrawNoTexture() { + mCaches.disbaleTexCoordsVertexArray(); +} + void OpenGLRenderer::setupDrawAALine() { mDescription.isAA = true; } @@ -1194,25 +1203,21 @@ void OpenGLRenderer::setupDrawColorFilterUniforms() { } void OpenGLRenderer::setupDrawSimpleMesh() { - mCaches.bindMeshBuffer(); - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gMeshStride, 0); + bool force = mCaches.bindMeshBuffer(); + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, 0); + mCaches.unbindIndicesBuffer(); } void OpenGLRenderer::setupDrawTexture(GLuint texture) { bindTexture(texture); - glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++); - - mTexCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); - glEnableVertexAttribArray(mTexCoordsSlot); + mTextureUnit++; + mCaches.enableTexCoordsVertexArray(); } void OpenGLRenderer::setupDrawExternalTexture(GLuint texture) { bindExternalTexture(texture); - glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++); - - mTexCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); - glEnableVertexAttribArray(mTexCoordsSlot); + mTextureUnit++; + mCaches.enableTexCoordsVertexArray(); } void OpenGLRenderer::setupDrawTextureTransform() { @@ -1225,22 +1230,34 @@ void OpenGLRenderer::setupDrawTextureTransformUniforms(mat4& transform) { } void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) { + bool force = false; if (!vertices) { - mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); + force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); } else { - mCaches.unbindMeshBuffer(); + force = mCaches.unbindMeshBuffer(); } - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gMeshStride, vertices); - if (mTexCoordsSlot >= 0) { - glVertexAttribPointer(mTexCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords); + + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, vertices); + if (mCaches.currentProgram->texCoords >= 0) { + mCaches.bindTexCoordsVertexPointer(force, mCaches.currentProgram->texCoords, texCoords); + } + + mCaches.unbindIndicesBuffer(); +} + +void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords) { + bool force = mCaches.unbindMeshBuffer(); + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, vertices); + if (mCaches.currentProgram->texCoords >= 0) { + mCaches.bindTexCoordsVertexPointer(force, mCaches.currentProgram->texCoords, texCoords); } } void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) { - mCaches.unbindMeshBuffer(); - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gVertexStride, vertices); + bool force = mCaches.unbindMeshBuffer(); + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, + vertices, gVertexStride); + mCaches.unbindIndicesBuffer(); } /** @@ -1256,24 +1273,29 @@ void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) { */ void OpenGLRenderer::setupDrawAALine(GLvoid* vertices, GLvoid* widthCoords, GLvoid* lengthCoords, float boundaryWidthProportion) { - mCaches.unbindMeshBuffer(); - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gAAVertexStride, vertices); + bool force = mCaches.unbindMeshBuffer(); + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, + vertices, gAAVertexStride); + mCaches.resetTexCoordsVertexPointer(); + mCaches.unbindIndicesBuffer(); + int widthSlot = mCaches.currentProgram->getAttrib("vtxWidth"); glEnableVertexAttribArray(widthSlot); glVertexAttribPointer(widthSlot, 1, GL_FLOAT, GL_FALSE, gAAVertexStride, widthCoords); + int lengthSlot = mCaches.currentProgram->getAttrib("vtxLength"); glEnableVertexAttribArray(lengthSlot); glVertexAttribPointer(lengthSlot, 1, GL_FLOAT, GL_FALSE, gAAVertexStride, lengthCoords); + int boundaryWidthSlot = mCaches.currentProgram->getUniform("boundaryWidth"); glUniform1f(boundaryWidthSlot, boundaryWidthProportion); + // Setting the inverse value saves computations per-fragment in the shader int inverseBoundaryWidthSlot = mCaches.currentProgram->getUniform("inverseBoundaryWidth"); glUniform1f(inverseBoundaryWidthSlot, (1 / boundaryWidthProportion)); } void OpenGLRenderer::finishDrawTexture() { - glDisableVertexAttribArray(mTexCoordsSlot); } /////////////////////////////////////////////////////////////////////////////// @@ -1316,6 +1338,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f); ignoreTransform = true; filter = GL_NEAREST; + } else { + filter = FILTER(paint); } setupDraw(); @@ -1330,8 +1354,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk setupDrawModelView(x, y, x + texture->width, y + texture->height, ignoreTransform); setupDrawTexture(texture->id); - texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); - texture->setFilter(filter, filter); + texture->setWrap(GL_CLAMP_TO_EDGE); + texture->setFilter(filter); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(); @@ -1351,7 +1375,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -1372,7 +1396,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -1392,13 +1416,13 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); - texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true); - texture->setFilter(GL_LINEAR, GL_LINEAR, true); + texture->setWrap(GL_CLAMP_TO_EDGE, true); + texture->setFilter(FILTER(paint), true); int alpha; SkXfermode::Mode mode; @@ -1477,11 +1501,10 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); - texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true); const float width = texture->width; const float height = texture->height; @@ -1498,6 +1521,8 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); + texture->setWrap(GL_CLAMP_TO_EDGE, true); + if (mSnapshot->transform->isPureTranslate()) { const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f); const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f); @@ -1505,17 +1530,16 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, GLenum filter = GL_NEAREST; // Enable linear filtering if the source rectangle is scaled if (srcRight - srcLeft != dstRight - dstLeft || srcBottom - srcTop != dstBottom - dstTop) { - filter = GL_LINEAR; + filter = FILTER(paint); } - texture->setFilter(filter, filter, true); + texture->setFilter(filter, true); drawTextureMesh(x, y, x + (dstRight - dstLeft), y + (dstBottom - dstTop), texture->id, alpha / 255.0f, mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount, false, true); } else { - texture->setFilter(GL_LINEAR, GL_LINEAR, true); - + texture->setFilter(FILTER(paint), true); drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f, mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount); @@ -1531,12 +1555,12 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); - texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true); - texture->setFilter(GL_LINEAR, GL_LINEAR, true); + texture->setWrap(GL_CLAMP_TO_EDGE, true); + texture->setFilter(GL_LINEAR, true); int alpha; SkXfermode::Mode mode; @@ -1610,6 +1634,7 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom } setupDraw(); + setupDrawNoTexture(); setupDrawAALine(); setupDrawColor(color); setupDrawColorFilter(); @@ -1720,6 +1745,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { getAlphaAndMode(paint, &alpha, &mode); setupDraw(); + setupDrawNoTexture(); if (isAA) { setupDrawAALine(); } @@ -1929,6 +1955,7 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) { TextureVertex* vertex = &pointsData[0]; setupDraw(); + setupDrawNoTexture(); setupDrawPoint(strokeWidth); setupDrawColor(paint->getColor(), alpha); setupDrawColorFilter(); @@ -1979,7 +2006,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot float rx, float ry, SkPaint* paint) { if (mSnapshot->isIgnored()) return; - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect( right - left, bottom - top, rx, ry, paint); drawShape(left, top, texture, paint); @@ -1988,7 +2015,7 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { if (mSnapshot->isIgnored()) return; - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint); drawShape(x - radius, y - radius, texture, paint); } @@ -1996,7 +2023,7 @@ void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { if (mSnapshot->isIgnored()) return; - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint); drawShape(left, top, texture, paint); } @@ -2010,7 +2037,7 @@ void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top, startAngle, sweepAngle, useCenter, paint); drawShape(left, top, texture, paint); @@ -2020,7 +2047,7 @@ void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float b SkPaint* paint) { if (mSnapshot->isIgnored()) return; - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint); drawShape(left, top, texture, paint); } @@ -2055,37 +2082,35 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, } void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, - float x, float y, SkPaint* paint) { + float x, float y, SkPaint* paint, float length) { if (text == NULL || count == 0) { return; } if (mSnapshot->isIgnored()) return; - // TODO: We should probably make a copy of the paint instead of modifying - // it; modifying the paint will change its generationID the first - // time, which might impact caches. More investigation needed to - // see if it matters. - // If we make a copy, then drawTextDecorations() should *not* make - // its own copy as it does right now. - paint->setAntiAlias(true); -#if RENDER_TEXT_AS_GLYPHS - paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); -#endif + // NOTE: AA and glyph id encoding are set in DisplayListRenderer.cpp - float length = -1.0f; switch (paint->getTextAlign()) { case SkPaint::kCenter_Align: - length = paint->measureText(text, bytesCount); + if (length < 0.0f) length = paint->measureText(text, bytesCount); x -= length / 2.0f; break; case SkPaint::kRight_Align: - length = paint->measureText(text, bytesCount); + if (length < 0.0f) length = paint->measureText(text, bytesCount); x -= length; break; default: break; } + SkPaint::FontMetrics metrics; + paint->getFontMetrics(&metrics, 0.0f); + // If no length was specified, just perform the hit test on the Y axis + if (quickReject(x, y + metrics.fTop, + x + (length >= 0.0f ? length : INT_MAX / 2), y + metrics.fBottom)) { + return; + } + const float oldX = x; const float oldY = y; const bool pureTranslate = mSnapshot->transform->isPureTranslate(); @@ -2095,6 +2120,9 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint); +#if DEBUG_GLYPHS + LOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); +#endif fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize()); @@ -2103,6 +2131,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, getAlphaAndMode(paint, &alpha, &mode); if (mHasShadow) { + mCaches.activeTexture(0); + mCaches.dropShadowCache.setFontRenderer(fontRenderer); const ShadowTexture* shadow = mCaches.dropShadowCache.get( paint, text, bytesCount, count, mShadowRadius); @@ -2117,7 +2147,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, shadowColor = 0xffffffff; } - glActiveTexture(gTextureUnits[0]); setupDraw(); setupDrawWithTexture(true); setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha); @@ -2133,8 +2162,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); - - finishDrawTexture(); } if (paint->getAlpha() == 0 && paint->getXfermode() == NULL) { @@ -2147,7 +2174,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); setupDraw(); setupDrawDirtyRegionsDisabled(); setupDrawWithTexture(true); @@ -2170,12 +2197,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, #else bool hasActiveLayer = false; #endif - mCaches.unbindMeshBuffer(); - // Tell font renderer the locations of position and texture coord - // attributes so it can bind its data properly - int positionSlot = mCaches.currentProgram->position; - fontRenderer.setAttributeBindingSlots(positionSlot, mTexCoordsSlot); if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, hasActiveLayer ? &bounds : NULL)) { #if RENDER_LAYERS_AS_REGIONS @@ -2188,16 +2210,13 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, #endif } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords")); - drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); } void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { if (mSnapshot->isIgnored()) return; - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); const PathTexture* texture = mCaches.pathCache.get(path, paint); if (!texture) return; @@ -2214,7 +2233,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { return; } - glActiveTexture(gTextureUnits[0]); + mCaches.activeTexture(0); int alpha; SkXfermode::Mode mode; @@ -2243,11 +2262,11 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f); y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f); - layer->setFilter(GL_NEAREST, GL_NEAREST); + layer->setFilter(GL_NEAREST); setupDrawModelViewTranslate(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), true); } else { - layer->setFilter(GL_LINEAR, GL_LINEAR); + layer->setFilter(GL_LINEAR); setupDrawModelViewTranslate(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); } @@ -2420,6 +2439,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot } setupDraw(); + setupDrawNoTexture(); setupDrawColor(color); setupDrawShader(); setupDrawColorFilter(); @@ -2440,18 +2460,18 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); - texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true); + texture->setWrap(GL_CLAMP_TO_EDGE, true); if (mSnapshot->transform->isPureTranslate()) { const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f); const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f); - texture->setFilter(GL_NEAREST, GL_NEAREST, true); + texture->setFilter(GL_NEAREST, true); drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id, alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, false, true); } else { - texture->setFilter(GL_LINEAR, GL_LINEAR, true); + texture->setFilter(FILTER(paint), true); drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount); |
