diff options
author | Chris Craik <ccraik@google.com> | 2015-02-24 13:46:29 -0800 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2015-02-25 10:18:46 -0800 |
commit | 14100ac9f8efc1a2407e3f5a5c8b2532a49585db (patch) | |
tree | ddcbc13d5205d5a2ce47dc55506716a9490011b4 /libs | |
parent | cdd35e6776f1e699a507e4ebb3a19b5eb75dc0fb (diff) | |
download | frameworks_base-14100ac9f8efc1a2407e3f5a5c8b2532a49585db.zip frameworks_base-14100ac9f8efc1a2407e3f5a5c8b2532a49585db.tar.gz frameworks_base-14100ac9f8efc1a2407e3f5a5c8b2532a49585db.tar.bz2 |
Glop support for custom textured UVs, simplify drawBitmap(src,dst)
Front load the scaling-to-support-shaders to record time.
Change-Id: I861c82d9d16d3c5e063cf87230127eed0b3f9b54
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListOp.h | 4 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 27 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.cpp | 47 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.h | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 79 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 6 | ||||
-rw-r--r-- | libs/hwui/Renderer.h | 4 |
7 files changed, 100 insertions, 68 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index cca8a06..00942d7 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -713,9 +713,7 @@ public: mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { - renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, - mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, - mPaint); + renderer.drawBitmap(mBitmap, mSrc, mLocalBounds, mPaint); } virtual void output(int level, uint32_t logFlags) const override { diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 23181bc..2a673f4 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -258,7 +258,8 @@ void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, floa float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { if (srcLeft == 0 && srcTop == 0 - && srcRight == bitmap.width() && srcBottom == bitmap.height() + && srcRight == bitmap.width() + && srcBottom == bitmap.height() && (srcBottom - srcTop == dstBottom - dstTop) && (srcRight - srcLeft == dstRight - dstLeft)) { // transform simple rect to rect drawing case into position bitmap ops, since they merge @@ -269,6 +270,30 @@ void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, floa } else { paint = refPaint(paint); + if (paint && paint->getShader()) { + float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft); + float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop); + if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) { + // Apply the scale transform on the canvas, so that the shader + // effectively calculates positions relative to src rect space + + save(SkCanvas::kMatrix_SaveFlag); + translate(dstLeft, dstTop); + scale(scaleX, scaleY); + + dstLeft = 0.0f; + dstTop = 0.0f; + dstRight = srcRight - srcLeft; + dstBottom = srcBottom - srcTop; + + addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), + srcLeft, srcTop, srcRight, srcBottom, + dstLeft, dstTop, dstRight, dstBottom, paint)); + restore(); + return; + } + } + addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), srcLeft, srcTop, srcRight, srcBottom, dstLeft, dstTop, dstRight, dstBottom, paint)); diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 4617588..1342c52 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -32,7 +32,7 @@ namespace android { namespace uirenderer { #define TRIGGER_STAGE(stageFlag) \ - LOG_ALWAYS_FATAL_IF(stageFlag & mStageFlags, "Stage %d cannot be run twice"); \ + LOG_ALWAYS_FATAL_IF((stageFlag) & mStageFlags, "Stage %d cannot be run twice", (stageFlag)); \ mStageFlags = static_cast<StageFlags>(mStageFlags | (stageFlag)) #define REQUIRE_STAGES(requiredFlags) \ @@ -40,10 +40,10 @@ namespace uirenderer { "not prepared for current stage") static void setUnitQuadTextureCoords(Rect uvs, TextureVertex* quadVertex) { - TextureVertex::setUV(quadVertex++, uvs.left, uvs.top); - TextureVertex::setUV(quadVertex++, uvs.right, uvs.top); - TextureVertex::setUV(quadVertex++, uvs.left, uvs.bottom); - TextureVertex::setUV(quadVertex++, uvs.right, uvs.bottom); + quadVertex[0] = {0, 0, uvs.left, uvs.top}; + quadVertex[1] = {1, 0, uvs.right, uvs.top}; + quadVertex[2] = {0, 1, uvs.left, uvs.bottom}; + quadVertex[3] = {1, 1, uvs.right, uvs.bottom}; } GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop) @@ -74,25 +74,40 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() { } GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) { + if (uvMapper) { + // can't use unit quad VBO, so build UV vertices manually + return setMeshTexturedUvQuad(uvMapper, Rect(0, 0, 1, 1)); + } + + TRIGGER_STAGE(kMeshStage); + + mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib; + mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; + mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO(); + mOutGlop->mesh.vertices = nullptr; + mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset; + mOutGlop->mesh.indexBufferObject = 0; + mOutGlop->mesh.indices = nullptr; + mOutGlop->mesh.elementCount = 4; + mOutGlop->mesh.stride = kTextureVertexStride; + mDescription.hasTexture = true; + return *this; +} + +GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect uvs) { TRIGGER_STAGE(kMeshStage); mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; if (CC_UNLIKELY(uvMapper)) { - Rect uvs(0, 0, 1, 1); uvMapper->map(uvs); - setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]); - - mOutGlop->mesh.vertexBufferObject = 0; - mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0]; - mOutGlop->mesh.texCoordOffset = &mOutGlop->mesh.mappedVertices[0].u; - } else { - // standard UV coordinates, use regular unit quad VBO - mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO(); - mOutGlop->mesh.vertices = nullptr; - mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset; } + setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]); + + mOutGlop->mesh.vertexBufferObject = 0; + mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0].x; + mOutGlop->mesh.texCoordOffset = &mOutGlop->mesh.mappedVertices[0].u; mOutGlop->mesh.indexBufferObject = 0; mOutGlop->mesh.indices = nullptr; mOutGlop->mesh.elementCount = 4; diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index cbdd0cd..5a8354d 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -40,6 +40,7 @@ public: GlopBuilder& setMeshUnitQuad(); GlopBuilder& setMeshTexturedUnitQuad(const UvMapper* uvMapper); + GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount); GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index b62af3b..161da87e 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -2185,26 +2185,43 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m mDirty = true; } -void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, - float srcLeft, float srcTop, float srcRight, float srcBottom, - float dstLeft, float dstTop, float dstRight, float dstBottom, - const SkPaint* paint) { - if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) { +void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, const SkPaint* paint) { + if (quickRejectSetupScissor(dst)) { return; } - mCaches.textureState().activateTexture(0); Texture* texture = getTexture(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + if (USE_GLOPS) { + Rect uv(fmax(0.0f, src.left / texture->width), + fmax(0.0f, src.top / texture->height), + fmin(1.0f, src.right / texture->width), + fmin(1.0f, src.bottom / texture->height)); + + bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType; + Glop glop; + GlopBuilder aBuilder(mRenderState, mCaches, &glop); + aBuilder.setMeshTexturedUvQuad(texture->uvMapper, uv) + .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) + .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setModelViewMapUnitToRectSnap(dst) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); + return; + } + + mCaches.textureState().activateTexture(0); + const float width = texture->width; const float height = texture->height; - float u1 = fmax(0.0f, srcLeft / width); - float v1 = fmax(0.0f, srcTop / height); - float u2 = fmin(1.0f, srcRight / width); - float v2 = fmin(1.0f, srcBottom / height); + float u1 = fmax(0.0f, src.left / width); + float v1 = fmax(0.0f, src.top / height); + float u2 = fmin(1.0f, src.right / width); + float v2 = fmin(1.0f, src.bottom / height); getMapper(texture).map(u1, v1, u2, v2); @@ -2213,25 +2230,21 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, texture->setWrap(GL_CLAMP_TO_EDGE, true); - float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft); - float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop); + float scaleX = (dst.right - dst.left) / (src.right - src.left); + float scaleY = (dst.bottom - dst.top) / (src.bottom - src.top); bool scaled = scaleX != 1.0f || scaleY != 1.0f; - // Apply a scale transform on the canvas only when a shader is in use - // Skia handles the ratio between the dst and src rects as a scale factor - // when a shader is set - bool useScaleTransform = getShader(paint) && scaled; bool ignoreTransform = false; - if (CC_LIKELY(currentTransform()->isPureTranslate() && !useScaleTransform)) { - float x = (int) floorf(dstLeft + currentTransform()->getTranslateX() + 0.5f); - float y = (int) floorf(dstTop + currentTransform()->getTranslateY() + 0.5f); + if (CC_LIKELY(currentTransform()->isPureTranslate())) { + float x = (int) floorf(dst.left + currentTransform()->getTranslateX() + 0.5f); + float y = (int) floorf(dst.top + currentTransform()->getTranslateY() + 0.5f); - dstRight = x + (dstRight - dstLeft); - dstBottom = y + (dstBottom - dstTop); + dst.right = x + (dst.right - dst.left); + dst.bottom = y + (dst.bottom - dst.top); - dstLeft = x; - dstTop = y; + dst.left = x; + dst.top = y; texture->setFilter(scaled ? PaintUtils::getFilter(paint) : GL_NEAREST, true); ignoreTransform = true; @@ -2239,34 +2252,18 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, texture->setFilter(PaintUtils::getFilter(paint), true); } - if (CC_UNLIKELY(useScaleTransform)) { - save(SkCanvas::kMatrix_SaveFlag); - translate(dstLeft, dstTop); - scale(scaleX, scaleY); - - dstLeft = 0.0f; - dstTop = 0.0f; - - dstRight = srcRight - srcLeft; - dstBottom = srcBottom - srcTop; - } - if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { - drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom, + drawAlpha8TextureMesh(dst.left, dst.top, dst.right, dst.bottom, texture->id, paint, &mMeshVertices[0].x, &mMeshVertices[0].u, GL_TRIANGLE_STRIP, kUnitQuadCount, ignoreTransform); } else { - drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, + drawTextureMesh(dst.left, dst.top, dst.right, dst.bottom, texture->id, paint, texture->blend, &mMeshVertices[0].x, &mMeshVertices[0].u, GL_TRIANGLE_STRIP, kUnitQuadCount, false, ignoreTransform); } - if (CC_UNLIKELY(useScaleTransform)) { - restore(); - } - resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); mDirty = true; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 851effa..8547b67 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -160,9 +160,8 @@ public: virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) override; void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint); - virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, - float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, const SkPaint* paint) override; + virtual void drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, + const SkPaint* paint) override; virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) override; void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, @@ -478,7 +477,6 @@ protected: return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion(); } - /** * Renders the specified layer as a textured quad. * diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index 48d83b9..1e737c0 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -152,9 +152,7 @@ public: // Bitmap-based virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0; - virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, - float srcRight, float srcBottom, float dstLeft, float dstTop, - float dstRight, float dstBottom, const SkPaint* paint) = 0; + virtual void drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, const SkPaint* paint) = 0; virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) = 0; virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, |