Loading libs/hwui/GlopBuilder.cpp +21 −5 Original line number Diff line number Diff line Loading @@ -139,6 +139,20 @@ GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, return *this; } GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int elementCount) { TRIGGER_STAGE(kMeshStage); mOutGlop->mesh.primitiveMode = GL_TRIANGLES; mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { 0, VertexAttribFlags::kTextureCoord, &vertexData[0].x, &vertexData[0].u, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; return *this; } GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) { TRIGGER_STAGE(kMeshStage); Loading Loading @@ -269,19 +283,21 @@ void GlopBuilder::setFill(int color, float alphaScale, SkXfermode::Mode mode, } } GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture, GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillFlags, const SkPaint* paint, float alphaScale) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage); GLenum filter = (textureFillFlags & TextureFillFlags::kForceFilter) ? GL_LINEAR : PaintUtils::getFilter(paint); mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE, nullptr }; GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr }; if (paint) { int color = paint->getColor(); SkShader* shader = paint->getShader(); if (!isAlphaMaskTexture) { if (!(textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture)) { // Texture defines color, so disable shaders, and reset all non-alpha color channels color |= 0x00FFFFFF; shader = nullptr; Loading @@ -303,9 +319,9 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMask } } mDescription.hasAlpha8Texture = isAlphaMaskTexture; if (isAlphaMaskTexture) { if (textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture) { mDescription.modulate = mOutGlop->fill.color.isNotBlack(); mDescription.hasAlpha8Texture = true; } else { mDescription.modulate = mOutGlop->fill.color.a < 1.0f; } Loading libs/hwui/GlopBuilder.h +19 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,13 @@ class Texture; class VertexBuffer; struct Glop; enum class TextureFillFlags { kNone = 0, kIsAlphaMaskTexture = 1 << 0, kForceFilter = 1 << 1, }; MAKE_FLAGS_ENUM(TextureFillFlags); class GlopBuilder { PREVENT_COPY_AND_ASSIGN(GlopBuilder); public: Loading @@ -43,11 +50,12 @@ public: GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount); GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: use indexed quads GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); // TODO: use indexed quads GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale); GlopBuilder& setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture, GlopBuilder& setFillTexturePaint(Texture& texture, int textureFillFlags, const SkPaint* paint, float alphaScale); GlopBuilder& setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint, float alphaScale); Loading @@ -63,7 +71,7 @@ public: GlopBuilder& setModelViewMapUnitToRect(const Rect destination); GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination); GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect destination) { GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect& destination) { if (snap) { return setModelViewMapUnitToRectSnap(destination); } else { Loading @@ -72,6 +80,14 @@ public: } GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source); GlopBuilder& setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source); GlopBuilder& setModelViewOffsetRectOptionalSnap(bool snap, float offsetX, float offsetY, const Rect& source) { if (snap) { return setModelViewOffsetRectSnap(offsetX, offsetY, source); } else { return setModelViewOffsetRect(offsetX, offsetY, source); } } GlopBuilder& setRoundRectClipState(const RoundRectClipState* roundRectClipState); Loading libs/hwui/OpenGLRenderer.cpp +105 −80 Original line number Diff line number Diff line Loading @@ -883,8 +883,8 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { && !layer->getForceFilter() && layer->getWidth() == (uint32_t) rect.getWidth() && layer->getHeight() == (uint32_t) rect.getHeight()) { const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); setupDrawModelView(kModelViewMode_TranslateAndScale, false, Loading Loading @@ -921,8 +921,8 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) if (simpleTransform) { // When we're swapping, the layer is already in screen coordinates if (!swap) { x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); } layer->setFilter(GL_NEAREST, true); Loading Loading @@ -1076,8 +1076,8 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { setupDrawColorFilterUniforms(layer->getColorFilter()); setupDrawTexture(layer->getTextureId()); if (currentTransform()->isPureTranslate()) { const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); setupDrawModelView(kModelViewMode_Translate, false, Loading Loading @@ -2004,8 +2004,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) { bool ignoreTransform = false; if (currentTransform()->isPureTranslate()) { x = (int) floorf(currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(currentTransform()->getTranslateY() + 0.5f); x = floorf(currentTransform()->getTranslateX() + 0.5f); y = floorf(currentTransform()->getTranslateY() + 0.5f); ignoreTransform = true; texture->setFilter(GL_NEAREST, true); Loading @@ -2028,17 +2028,37 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) { void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); if (USE_GLOPS) { // TODO: remove layer dirty in multi-draw callers // TODO: snap doesn't need to touch transform, only texture filter. bool snap = pureTranslate; const float x = floorf(bounds.left + 0.5f); const float y = floorf(bounds.top + 0.5f); int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedMesh(vertices, bitmapCount * 6) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); return; } mCaches.textureState().activateTexture(0); texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(pureTranslate ? GL_NEAREST : PaintUtils::getFilter(paint), true); const float x = (int) floorf(bounds.left + 0.5f); const float y = (int) floorf(bounds.top + 0.5f); const float x = floorf(bounds.left + 0.5f); const float y = floorf(bounds.top + 0.5f); if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(), texture->id, paint, &vertices[0].x, &vertices[0].u, Loading @@ -2065,11 +2085,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { const AutoTexture autoCleanup(texture); if (USE_GLOPS) { bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType; int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUnitQuad(texture->uvMapper) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2166,11 +2187,10 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m * TODO: handle alpha_8 textures correctly by applying paint color, but *not* * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh. */ bool isAlpha8Texture = false; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshColoredTexturedMesh(mesh.get(), elementCount) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, static_cast<int>(TextureFillFlags::kNone), paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2229,11 +2249,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons fmin(1.0f, src.right / texture->width), fmin(1.0f, src.bottom / texture->height)); bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType; int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUvQuad(texture->uvMapper, uv) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewMapUnitToRectSnap(dst) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2266,8 +2287,8 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons bool ignoreTransform = false; 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); float x = floorf(dst.left + currentTransform()->getTranslateX() + 0.5f); float y = floorf(dst.top + currentTransform()->getTranslateY() + 0.5f); dst.right = x + (dst.right - dst.left); dst.bottom = y + (dst.bottom - dst.top); Loading Loading @@ -2298,27 +2319,13 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons mDirty = true; } void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { return; } AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap); const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(), right - left, bottom - top, patch); drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); } void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { if (!mesh || !mesh->verticesCount || quickRejectSetupScissor(left, top, right, bottom)) { return; } if (CC_LIKELY(mesh && mesh->verticesCount > 0)) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; Loading @@ -2336,8 +2343,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, for (size_t i = 0; i < count; i++) { const Rect& bounds = mesh->quads.itemAt(i); if (CC_LIKELY(pureTranslate)) { const float x = (int) floorf(bounds.left + offsetX + 0.5f); const float y = (int) floorf(bounds.top + offsetY + 0.5f); const float x = floorf(bounds.left + offsetX + 0.5f); const float y = floorf(bounds.top + offsetY + 0.5f); dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight()); } else { dirtyLayer(left + bounds.left, top + bounds.top, Loading @@ -2348,8 +2355,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, bool ignoreTransform = false; if (CC_LIKELY(pureTranslate)) { const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(top + currentTransform()->getTranslateY() + 0.5f); right = x + right - left; bottom = y + bottom - top; Loading @@ -2361,7 +2368,6 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset, GL_TRIANGLES, mesh->indexCount, false, ignoreTransform, mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } mDirty = true; } Loading @@ -2372,18 +2378,37 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, * The caller is responsible for properly dirtying the current layer. */ void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) { TextureVertex* vertices, uint32_t elementCount, const SkPaint* paint) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); if (USE_GLOPS) { // TODO: get correct bounds from caller // 9 patches are built for stretching - always filter int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter); if (bitmap->colorType() == kAlpha_8_SkColorType) { textureFillFlags |= TextureFillFlags::kIsAlphaMaskTexture; } Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedIndexedQuads(vertices, elementCount) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); return; } texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(GL_LINEAR, true); drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, paint, texture->blend, &vertices[0].x, &vertices[0].u, GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); GL_TRIANGLES, elementCount, false, true, 0, kModelViewMode_Translate, false); mDirty = true; } Loading Loading @@ -2775,8 +2800,8 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, float y = 0.0f; const bool pureTranslate = currentTransform()->isPureTranslate(); if (pureTranslate) { x = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f); x = floorf(x + currentTransform()->getTranslateX() + 0.5f); y = floorf(y + currentTransform()->getTranslateY() + 0.5f); } FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); Loading Loading @@ -2914,8 +2939,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float const bool pureTranslate = transform.isPureTranslate(); if (CC_LIKELY(pureTranslate)) { x = (int) floorf(x + transform.getTranslateX() + 0.5f); y = (int) floorf(y + transform.getTranslateY() + 0.5f); x = floorf(x + transform.getTranslateX() + 0.5f); y = floorf(y + transform.getTranslateY() + 0.5f); } int alpha; Loading Loading @@ -3426,8 +3451,8 @@ void OpenGLRenderer::drawTextureRect(Texture* texture, const SkPaint* paint) { } if (CC_LIKELY(currentTransform()->isPureTranslate())) { const float x = (int) floorf(currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(currentTransform()->getTranslateY() + 0.5f); const float x = floorf(currentTransform()->getTranslateX() + 0.5f); const float y = floorf(currentTransform()->getTranslateY() + 0.5f); texture->setFilter(GL_NEAREST, true); drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id, Loading libs/hwui/OpenGLRenderer.h +0 −2 Original line number Diff line number Diff line Loading @@ -206,8 +206,6 @@ public: const float* vertices, const int* colors, const SkPaint* paint); void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint); void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint); void drawColor(int color, SkXfermode::Mode mode); Loading libs/hwui/utils/Macros.h +12 −0 Original line number Diff line number Diff line Loading @@ -36,9 +36,21 @@ #Type " must have standard layout") #define MAKE_FLAGS_ENUM(enumType) \ inline int operator|=(int lhs, enumType rhs) { \ return lhs | static_cast<int>(rhs); \ } \ inline int operator|(int lhs, enumType rhs) { \ return lhs | static_cast<int>(rhs); \ } \ inline int operator|(enumType lhs, int rhs) { \ return static_cast<int>(lhs) | rhs; \ } \ inline int operator|(enumType lhs, enumType rhs) { \ return static_cast<int>(lhs) | static_cast<int>(rhs); \ } \ inline int operator&=(int lhs, enumType rhs) { \ return lhs & static_cast<int>(rhs); \ } \ inline int operator&(int lhs, enumType rhs) { \ return lhs & static_cast<int>(rhs); \ } \ Loading Loading
libs/hwui/GlopBuilder.cpp +21 −5 Original line number Diff line number Diff line Loading @@ -139,6 +139,20 @@ GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, return *this; } GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int elementCount) { TRIGGER_STAGE(kMeshStage); mOutGlop->mesh.primitiveMode = GL_TRIANGLES; mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { 0, VertexAttribFlags::kTextureCoord, &vertexData[0].x, &vertexData[0].u, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; return *this; } GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) { TRIGGER_STAGE(kMeshStage); Loading Loading @@ -269,19 +283,21 @@ void GlopBuilder::setFill(int color, float alphaScale, SkXfermode::Mode mode, } } GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture, GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillFlags, const SkPaint* paint, float alphaScale) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage); GLenum filter = (textureFillFlags & TextureFillFlags::kForceFilter) ? GL_LINEAR : PaintUtils::getFilter(paint); mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE, nullptr }; GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr }; if (paint) { int color = paint->getColor(); SkShader* shader = paint->getShader(); if (!isAlphaMaskTexture) { if (!(textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture)) { // Texture defines color, so disable shaders, and reset all non-alpha color channels color |= 0x00FFFFFF; shader = nullptr; Loading @@ -303,9 +319,9 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMask } } mDescription.hasAlpha8Texture = isAlphaMaskTexture; if (isAlphaMaskTexture) { if (textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture) { mDescription.modulate = mOutGlop->fill.color.isNotBlack(); mDescription.hasAlpha8Texture = true; } else { mDescription.modulate = mOutGlop->fill.color.a < 1.0f; } Loading
libs/hwui/GlopBuilder.h +19 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,13 @@ class Texture; class VertexBuffer; struct Glop; enum class TextureFillFlags { kNone = 0, kIsAlphaMaskTexture = 1 << 0, kForceFilter = 1 << 1, }; MAKE_FLAGS_ENUM(TextureFillFlags); class GlopBuilder { PREVENT_COPY_AND_ASSIGN(GlopBuilder); public: Loading @@ -43,11 +50,12 @@ public: GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount); GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: use indexed quads GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); // TODO: use indexed quads GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale); GlopBuilder& setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture, GlopBuilder& setFillTexturePaint(Texture& texture, int textureFillFlags, const SkPaint* paint, float alphaScale); GlopBuilder& setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint, float alphaScale); Loading @@ -63,7 +71,7 @@ public: GlopBuilder& setModelViewMapUnitToRect(const Rect destination); GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination); GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect destination) { GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect& destination) { if (snap) { return setModelViewMapUnitToRectSnap(destination); } else { Loading @@ -72,6 +80,14 @@ public: } GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source); GlopBuilder& setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source); GlopBuilder& setModelViewOffsetRectOptionalSnap(bool snap, float offsetX, float offsetY, const Rect& source) { if (snap) { return setModelViewOffsetRectSnap(offsetX, offsetY, source); } else { return setModelViewOffsetRect(offsetX, offsetY, source); } } GlopBuilder& setRoundRectClipState(const RoundRectClipState* roundRectClipState); Loading
libs/hwui/OpenGLRenderer.cpp +105 −80 Original line number Diff line number Diff line Loading @@ -883,8 +883,8 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { && !layer->getForceFilter() && layer->getWidth() == (uint32_t) rect.getWidth() && layer->getHeight() == (uint32_t) rect.getHeight()) { const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); setupDrawModelView(kModelViewMode_TranslateAndScale, false, Loading Loading @@ -921,8 +921,8 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) if (simpleTransform) { // When we're swapping, the layer is already in screen coordinates if (!swap) { x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); } layer->setFilter(GL_NEAREST, true); Loading Loading @@ -1076,8 +1076,8 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { setupDrawColorFilterUniforms(layer->getColorFilter()); setupDrawTexture(layer->getTextureId()); if (currentTransform()->isPureTranslate()) { const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f); layer->setFilter(GL_NEAREST); setupDrawModelView(kModelViewMode_Translate, false, Loading Loading @@ -2004,8 +2004,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) { bool ignoreTransform = false; if (currentTransform()->isPureTranslate()) { x = (int) floorf(currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(currentTransform()->getTranslateY() + 0.5f); x = floorf(currentTransform()->getTranslateX() + 0.5f); y = floorf(currentTransform()->getTranslateY() + 0.5f); ignoreTransform = true; texture->setFilter(GL_NEAREST, true); Loading @@ -2028,17 +2028,37 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) { void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount, TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); if (USE_GLOPS) { // TODO: remove layer dirty in multi-draw callers // TODO: snap doesn't need to touch transform, only texture filter. bool snap = pureTranslate; const float x = floorf(bounds.left + 0.5f); const float y = floorf(bounds.top + 0.5f); int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedMesh(vertices, bitmapCount * 6) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); return; } mCaches.textureState().activateTexture(0); texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(pureTranslate ? GL_NEAREST : PaintUtils::getFilter(paint), true); const float x = (int) floorf(bounds.left + 0.5f); const float y = (int) floorf(bounds.top + 0.5f); const float x = floorf(bounds.left + 0.5f); const float y = floorf(bounds.top + 0.5f); if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) { drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(), texture->id, paint, &vertices[0].x, &vertices[0].u, Loading @@ -2065,11 +2085,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { const AutoTexture autoCleanup(texture); if (USE_GLOPS) { bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType; int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUnitQuad(texture->uvMapper) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2166,11 +2187,10 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m * TODO: handle alpha_8 textures correctly by applying paint color, but *not* * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh. */ bool isAlpha8Texture = false; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshColoredTexturedMesh(mesh.get(), elementCount) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, static_cast<int>(TextureFillFlags::kNone), paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2229,11 +2249,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons fmin(1.0f, src.right / texture->width), fmin(1.0f, src.bottom / texture->height)); bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType; int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUvQuad(texture->uvMapper, uv) .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) .setModelViewMapUnitToRectSnap(dst) .setRoundRectClipState(currentSnapshot()->roundRectClipState) Loading Loading @@ -2266,8 +2287,8 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons bool ignoreTransform = false; 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); float x = floorf(dst.left + currentTransform()->getTranslateX() + 0.5f); float y = floorf(dst.top + currentTransform()->getTranslateY() + 0.5f); dst.right = x + (dst.right - dst.left); dst.bottom = y + (dst.bottom - dst.top); Loading Loading @@ -2298,27 +2319,13 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons mDirty = true; } void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { return; } AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap); const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(), right - left, bottom - top, patch); drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint); } void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint) { if (quickRejectSetupScissor(left, top, right, bottom)) { if (!mesh || !mesh->verticesCount || quickRejectSetupScissor(left, top, right, bottom)) { return; } if (CC_LIKELY(mesh && mesh->verticesCount > 0)) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; Loading @@ -2336,8 +2343,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, for (size_t i = 0; i < count; i++) { const Rect& bounds = mesh->quads.itemAt(i); if (CC_LIKELY(pureTranslate)) { const float x = (int) floorf(bounds.left + offsetX + 0.5f); const float y = (int) floorf(bounds.top + offsetY + 0.5f); const float x = floorf(bounds.left + offsetX + 0.5f); const float y = floorf(bounds.top + offsetY + 0.5f); dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight()); } else { dirtyLayer(left + bounds.left, top + bounds.top, Loading @@ -2348,8 +2355,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, bool ignoreTransform = false; if (CC_LIKELY(pureTranslate)) { const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f); const float x = floorf(left + currentTransform()->getTranslateX() + 0.5f); const float y = floorf(top + currentTransform()->getTranslateY() + 0.5f); right = x + right - left; bottom = y + bottom - top; Loading @@ -2361,7 +2368,6 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset, GL_TRIANGLES, mesh->indexCount, false, ignoreTransform, mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads); } mDirty = true; } Loading @@ -2372,18 +2378,37 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, * The caller is responsible for properly dirtying the current layer. */ void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) { TextureVertex* vertices, uint32_t elementCount, const SkPaint* paint) { mCaches.textureState().activateTexture(0); Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); if (USE_GLOPS) { // TODO: get correct bounds from caller // 9 patches are built for stretching - always filter int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter); if (bitmap->colorType() == kAlpha_8_SkColorType) { textureFillFlags |= TextureFillFlags::kIsAlphaMaskTexture; } Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedIndexedQuads(vertices, elementCount) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); return; } texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(GL_LINEAR, true); drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, paint, texture->blend, &vertices[0].x, &vertices[0].u, GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false); GL_TRIANGLES, elementCount, false, true, 0, kModelViewMode_Translate, false); mDirty = true; } Loading Loading @@ -2775,8 +2800,8 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, float y = 0.0f; const bool pureTranslate = currentTransform()->isPureTranslate(); if (pureTranslate) { x = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f); y = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f); x = floorf(x + currentTransform()->getTranslateX() + 0.5f); y = floorf(y + currentTransform()->getTranslateY() + 0.5f); } FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); Loading Loading @@ -2914,8 +2939,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float const bool pureTranslate = transform.isPureTranslate(); if (CC_LIKELY(pureTranslate)) { x = (int) floorf(x + transform.getTranslateX() + 0.5f); y = (int) floorf(y + transform.getTranslateY() + 0.5f); x = floorf(x + transform.getTranslateX() + 0.5f); y = floorf(y + transform.getTranslateY() + 0.5f); } int alpha; Loading Loading @@ -3426,8 +3451,8 @@ void OpenGLRenderer::drawTextureRect(Texture* texture, const SkPaint* paint) { } if (CC_LIKELY(currentTransform()->isPureTranslate())) { const float x = (int) floorf(currentTransform()->getTranslateX() + 0.5f); const float y = (int) floorf(currentTransform()->getTranslateY() + 0.5f); const float x = floorf(currentTransform()->getTranslateX() + 0.5f); const float y = floorf(currentTransform()->getTranslateY() + 0.5f); texture->setFilter(GL_NEAREST, true); drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id, Loading
libs/hwui/OpenGLRenderer.h +0 −2 Original line number Diff line number Diff line Loading @@ -206,8 +206,6 @@ public: const float* vertices, const int* colors, const SkPaint* paint); void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry, TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint); void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, float left, float top, float right, float bottom, const SkPaint* paint); void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry, float left, float top, float right, float bottom, const SkPaint* paint); void drawColor(int color, SkXfermode::Mode mode); Loading
libs/hwui/utils/Macros.h +12 −0 Original line number Diff line number Diff line Loading @@ -36,9 +36,21 @@ #Type " must have standard layout") #define MAKE_FLAGS_ENUM(enumType) \ inline int operator|=(int lhs, enumType rhs) { \ return lhs | static_cast<int>(rhs); \ } \ inline int operator|(int lhs, enumType rhs) { \ return lhs | static_cast<int>(rhs); \ } \ inline int operator|(enumType lhs, int rhs) { \ return static_cast<int>(lhs) | rhs; \ } \ inline int operator|(enumType lhs, enumType rhs) { \ return static_cast<int>(lhs) | static_cast<int>(rhs); \ } \ inline int operator&=(int lhs, enumType rhs) { \ return lhs & static_cast<int>(rhs); \ } \ inline int operator&(int lhs, enumType rhs) { \ return lhs & static_cast<int>(rhs); \ } \ Loading