summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2015-02-24 13:46:29 -0800
committerChris Craik <ccraik@google.com>2015-02-25 10:18:46 -0800
commit14100ac9f8efc1a2407e3f5a5c8b2532a49585db (patch)
treeddcbc13d5205d5a2ce47dc55506716a9490011b4 /libs
parentcdd35e6776f1e699a507e4ebb3a19b5eb75dc0fb (diff)
downloadframeworks_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.h4
-rw-r--r--libs/hwui/DisplayListRenderer.cpp27
-rw-r--r--libs/hwui/GlopBuilder.cpp47
-rw-r--r--libs/hwui/GlopBuilder.h1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp79
-rwxr-xr-xlibs/hwui/OpenGLRenderer.h6
-rw-r--r--libs/hwui/Renderer.h4
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,