Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b55f377 authored by Romain Guy's avatar Romain Guy
Browse files

Fix drawing issues with layers.

Prior to this change layers would clip their content incorrectly. They would
also not apply alpha properly.

Change-Id: Id7b3aaa7dbdc51de68fe050e64458f68e40503fd
parent 5aaeaffd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    static final String LOG_TAG = "TextView";
    static final boolean DEBUG_EXTRACT = false;
    
    private static int PRIORITY = 100;
    private static final int PRIORITY = 100;

    private ColorStateList mTextColor;
    private int mCurTextColor;
+34 −13
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ namespace uirenderer {
#define DEFAULT_PATH_CACHE_SIZE 6.0f
#define DEFAULT_PATCH_CACHE_SIZE 100
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 1.0f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f

#define REQUIRED_TEXTURE_UNITS_COUNT 3

@@ -251,13 +251,13 @@ bool OpenGLRenderer::restoreSnapshot() {
        mOrthoMatrix.load(current->orthoMatrix);
    }

    mSaveCount--;
    mSnapshot = previous;

    if (restoreLayer) {
        composeLayer(current, previous);
    }

    mSaveCount--;
    mSnapshot = previous;

    if (restoreClip) {
        setScissorFromClip();
    }
@@ -287,7 +287,11 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
        mode = SkXfermode::kSrcOver_Mode;
    }

    if (alpha > 0 && !mSnapshot->invisible) {
        createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags);
    } else {
        mSnapshot->invisible = true;
    }

    return count;
}
@@ -295,7 +299,11 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
        int alpha, int flags) {
    int count = saveSnapshot();
    if (alpha > 0 && !mSnapshot->invisible) {
        createLayer(mSnapshot, left, top, right, bottom, alpha, SkXfermode::kSrcOver_Mode, flags);
    } else {
        mSnapshot->invisible = true;
    }
    return count;
}

@@ -328,7 +336,6 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
    snapshot->flags |= Snapshot::kFlagIsLayer;
    snapshot->layer = layer;
    snapshot->fbo = layer->fbo;

    snapshot->transform.loadTranslate(-left, -top, 0.0f);
    snapshot->setClip(0.0f, 0.0f, right - left, bottom - top);
    snapshot->viewport.set(0.0f, 0.0f, right - left, bottom - top);
@@ -340,8 +347,7 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,

    // Change the ortho projection
    glViewport(0, 0, right - left, bottom - top);
    // Don't flip the FBO, it will get flipped when drawing back to the framebuffer
    mOrthoMatrix.loadOrtho(0.0f, right - left, 0.0f, bottom - top, -1.0f, 1.0f);
    mOrthoMatrix.loadOrtho(0.0f, right - left, bottom - top, 0.0f, -1.0f, 1.0f);

    return true;
}
@@ -363,9 +369,14 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
    Layer* layer = current->layer;
    const Rect& rect = layer->layer;

    // FBOs are already drawn with a top-left origin, don't flip the texture
    resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f);

    drawTextureRect(rect.left, rect.top, rect.right, rect.bottom,
            layer->texture, layer->alpha, layer->mode, layer->blend);

    resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);

    LayerSize size(rect.getWidth(), rect.getHeight());
    // Failing to add the layer to the cache should happen only if the
    // layer is too large
@@ -422,6 +433,8 @@ const Rect& OpenGLRenderer::getClipBounds() {
}

bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
    if (mSnapshot->invisible) return true;

    Rect r(left, top, right, bottom);
    mSnapshot->transform.mapRect(r);
    return !mSnapshot->clipRect.intersects(r);
@@ -527,6 +540,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
}

void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
    if (mSnapshot->invisible) return;
    const Rect& clip = mSnapshot->clipRect;
    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
@@ -556,7 +570,8 @@ 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) {
    if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
    if (mSnapshot->invisible || text == NULL || count == 0 ||
            (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
        return;
    }

@@ -614,6 +629,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
}

void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
    if (mSnapshot->invisible) return;

    GLuint textureUnit = 0;
    glActiveTexture(gTextureUnits[textureUnit]);

@@ -621,6 +638,13 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    const float x = texture->left - texture->offset;
    const float y = texture->top - texture->offset;

    if (quickReject(x, y, x + texture->width, y + texture->height)) {
        return;
    }

    int alpha;
    SkXfermode::Mode mode;
    getAlphaAndMode(paint, &alpha, &mode);
@@ -631,9 +655,6 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
    const GLfloat g = a * ((color >>  8) & 0xFF) / 255.0f;
    const GLfloat b = a * ((color      ) & 0xFF) / 255.0f;

    const float x = texture->left - texture->offset;
    const float y = texture->top - texture->offset;

    setupTextureAlpha8(texture, textureUnit, x, y, r, g, b, a, mode, true, true);

    // Draw the mesh
+7 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ namespace uirenderer {
 */
class Snapshot: public LightRefBase<Snapshot> {
public:
    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) { }
    Snapshot(): invisible(false), flags(0), previous(NULL), layer(NULL), fbo(0) { }

    /**
     * Copies the specified snapshot. Only the transform and clip rectangle
@@ -54,6 +54,7 @@ public:
            height(s->height),
            transform(s->transform),
            clipRect(s->clipRect),
            invisible(s->invisible),
            flags(0),
            previous(s),
            layer(NULL),
@@ -164,6 +165,11 @@ public:
     */
    Rect clipRect;

    /**
     * If true, the layer won't be rendered.
     */
    bool invisible;

    /**
     * Dirty flags.
     */