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

Commit 3a3133d8 authored by Romain Guy's avatar Romain Guy
Browse files

Update layers based on the dirty region.

Bug #3413433

This helps Launcher when a widget updates during a scroll, or when interacting
with widgets on the workspace if layers are still turned on.

Change-Id: Ic7a42eb34f74f4ae988039754f815e2efd1d1e4f
parent 849d0a37
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -73,7 +73,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.WeakHashMap;

/**
@@ -2375,6 +2374,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
    })
    int mLayerType = LAYER_TYPE_NONE;
    Paint mLayerPaint;
    Rect mLocalDirtyRect;

    /**
     * Simple constructor to use when creating a view from code.
@@ -8173,7 +8173,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        }

        mLayerType = layerType;
        mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : (paint == null ? new Paint() : paint);
        final boolean layerDisabled = mLayerType == LAYER_TYPE_NONE;
        mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint);
        mLocalDirtyRect = layerDisabled ? null : new Rect();

        invalidateParentCaches();
        invalidate(true);
@@ -8228,8 +8230,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
            mAttachInfo.mHardwareCanvas = canvas;
            try {
                canvas.setViewport(width, height);
                // TODO: We should pass the dirty rect
                canvas.onPreDraw(null);
                canvas.onPreDraw(mLocalDirtyRect);

                final int restoreCount = canvas.save();

@@ -8251,6 +8252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
                canvas.onPostDraw();
                mHardwareLayer.end(currentCanvas);
                mAttachInfo.mHardwareCanvas = currentCanvas;
                mLocalDirtyRect.setEmpty();
            }
        }

+20 −8
Original line number Diff line number Diff line
@@ -3487,17 +3487,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                if (child.mLayerType != LAYER_TYPE_NONE) {
                    mPrivateFlags |= INVALIDATED;
                    mPrivateFlags &= ~DRAWING_CACHE_VALID;
                    child.mLocalDirtyRect.setEmpty();
                }
                do {
                    View view = null;
                    if (parent instanceof View) {
                        view = (View) parent;
                        if (view.mLayerType != LAYER_TYPE_NONE &&
                                view.getParent() instanceof View) {
                        if (view.mLayerType != LAYER_TYPE_NONE) {
                            view.mLocalDirtyRect.setEmpty();
                            if (view.getParent() instanceof View) {
                                final View grandParent = (View) view.getParent();
                                grandParent.mPrivateFlags |= INVALIDATED;
                                grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID;
                            }
                        }
                        if ((view.mPrivateFlags & DIRTY_MASK) != 0) {
                            // already marked dirty - we're done
                            break;
@@ -3550,7 +3553,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                if (child.mLayerType != LAYER_TYPE_NONE) {
                    mPrivateFlags |= INVALIDATED;
                    mPrivateFlags &= ~DRAWING_CACHE_VALID;
                    child.mLocalDirtyRect.union(dirty);
                }

                do {
                    View view = null;
                    if (parent instanceof View) {
@@ -3631,6 +3636,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                    location[CHILD_LEFT_INDEX] = left;
                    location[CHILD_TOP_INDEX] = top;

                    if (mLayerType != LAYER_TYPE_NONE) {
                        mLocalDirtyRect.union(dirty);
                    }
                    
                    return mParent;
                }
            } else {
@@ -3639,8 +3648,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                location[CHILD_LEFT_INDEX] = mLeft;
                location[CHILD_TOP_INDEX] = mTop;

                dirty.set(0, 0, mRight - location[CHILD_LEFT_INDEX],
                        mBottom - location[CHILD_TOP_INDEX]);
                dirty.set(0, 0, mRight - mLeft, mBottom - mTop);

                if (mLayerType != LAYER_TYPE_NONE) {
                    mLocalDirtyRect.union(dirty);
                }

                return mParent;
            }
+16 −1
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

#define LOG_TAG "OpenGLRenderer"

#include <ui/Rect.h>

#include "LayerRenderer.h"
#include "Properties.h"
#include "Rect.h"

namespace android {
namespace uirenderer {
@@ -30,12 +33,24 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto
    LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);

#if RENDER_LAYERS_AS_REGIONS
    Rect dirty(left, top, right, bottom);
    if (dirty.isEmpty() || (dirty.left <= 0 && dirty.top <= 0 &&
            dirty.right >= mLayer->width && dirty.bottom >= mLayer->height)) {
        mLayer->region.clear();
        dirty.set(0.0f, 0.0f, mLayer->width, mLayer->height);
    } else {
        android::Rect r(dirty.left, dirty.top, dirty.right, dirty.bottom);
        mLayer->region.subtractSelf(r);
    }
#endif

    glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);

#if RENDER_LAYERS_AS_REGIONS
    OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
#else
    OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque);
#endif
}

void LayerRenderer::finish() {
+31 −19
Original line number Diff line number Diff line
@@ -671,6 +671,21 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
        finishDrawTexture();

#if DEBUG_LAYERS_AS_REGIONS
        drawRegionRects(layer->region);
#endif

        layer->region.clear();
    }
#else
    composeLayerRect(layer, rect);
#endif
}

void OpenGLRenderer::drawRegionRects(const Region& region) {
#if DEBUG_LAYERS_AS_REGIONS
    size_t count;
    const android::Rect* rects = region.getArray(&count);

    uint32_t colors[] = {
            0x7fff0000, 0x7f00ff00,
            0x7f0000ff, 0x7fff00ff,
@@ -678,7 +693,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {

    int offset = 0;
    int32_t top = rects[0].top;
        int i = 0;

    for (size_t i = 0; i < count; i++) {
        if (top != rects[i].top) {
@@ -691,12 +705,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
                SkXfermode::kSrcOver_Mode);
    }
#endif

        layer->region.clear();
    }
#else
    composeLayerRect(layer, rect);
#endif
}

void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1626,6 +1634,10 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
                    GL_UNSIGNED_SHORT, layer->meshIndices);

            finishDrawTexture();

#if DEBUG_LAYERS_AS_REGIONS
            drawRegionRects(layer->region);
#endif
        }
    }
#else
+2 −0
Original line number Diff line number Diff line
@@ -455,6 +455,8 @@ private:
    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
    void finishDrawTexture();

    void drawRegionRects(const Region& region);

    /**
     * Should be invoked every time the glScissor is modified.
     */