Loading core/java/android/view/View.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -73,7 +73,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.WeakHashMap; import java.util.WeakHashMap; /** /** Loading Loading @@ -2375,6 +2374,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility }) }) int mLayerType = LAYER_TYPE_NONE; int mLayerType = LAYER_TYPE_NONE; Paint mLayerPaint; Paint mLayerPaint; Rect mLocalDirtyRect; /** /** * Simple constructor to use when creating a view from code. * Simple constructor to use when creating a view from code. Loading Loading @@ -8173,7 +8173,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } mLayerType = layerType; 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(); invalidateParentCaches(); invalidate(true); invalidate(true); Loading Loading @@ -8228,8 +8230,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mAttachInfo.mHardwareCanvas = canvas; mAttachInfo.mHardwareCanvas = canvas; try { try { canvas.setViewport(width, height); canvas.setViewport(width, height); // TODO: We should pass the dirty rect canvas.onPreDraw(mLocalDirtyRect); canvas.onPreDraw(null); final int restoreCount = canvas.save(); final int restoreCount = canvas.save(); Loading @@ -8251,6 +8252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility canvas.onPostDraw(); canvas.onPostDraw(); mHardwareLayer.end(currentCanvas); mHardwareLayer.end(currentCanvas); mAttachInfo.mHardwareCanvas = currentCanvas; mAttachInfo.mHardwareCanvas = currentCanvas; mLocalDirtyRect.setEmpty(); } } } } Loading core/java/android/view/ViewGroup.java +20 −8 Original line number Original line Diff line number Diff line Loading @@ -3487,17 +3487,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.mLayerType != LAYER_TYPE_NONE) { if (child.mLayerType != LAYER_TYPE_NONE) { mPrivateFlags |= INVALIDATED; mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags &= ~DRAWING_CACHE_VALID; child.mLocalDirtyRect.setEmpty(); } } do { do { View view = null; View view = null; if (parent instanceof View) { if (parent instanceof View) { view = (View) parent; view = (View) parent; if (view.mLayerType != LAYER_TYPE_NONE && if (view.mLayerType != LAYER_TYPE_NONE) { view.getParent() instanceof View) { view.mLocalDirtyRect.setEmpty(); if (view.getParent() instanceof View) { final View grandParent = (View) view.getParent(); final View grandParent = (View) view.getParent(); grandParent.mPrivateFlags |= INVALIDATED; grandParent.mPrivateFlags |= INVALIDATED; grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; } } } if ((view.mPrivateFlags & DIRTY_MASK) != 0) { if ((view.mPrivateFlags & DIRTY_MASK) != 0) { // already marked dirty - we're done // already marked dirty - we're done break; break; Loading Loading @@ -3550,7 +3553,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.mLayerType != LAYER_TYPE_NONE) { if (child.mLayerType != LAYER_TYPE_NONE) { mPrivateFlags |= INVALIDATED; mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags &= ~DRAWING_CACHE_VALID; child.mLocalDirtyRect.union(dirty); } } do { do { View view = null; View view = null; if (parent instanceof View) { if (parent instanceof View) { Loading Loading @@ -3631,6 +3636,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = left; location[CHILD_LEFT_INDEX] = left; location[CHILD_TOP_INDEX] = top; location[CHILD_TOP_INDEX] = top; if (mLayerType != LAYER_TYPE_NONE) { mLocalDirtyRect.union(dirty); } return mParent; return mParent; } } } else { } else { Loading @@ -3639,8 +3648,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_TOP_INDEX] = mTop; location[CHILD_TOP_INDEX] = mTop; dirty.set(0, 0, mRight - location[CHILD_LEFT_INDEX], dirty.set(0, 0, mRight - mLeft, mBottom - mTop); mBottom - location[CHILD_TOP_INDEX]); if (mLayerType != LAYER_TYPE_NONE) { mLocalDirtyRect.union(dirty); } return mParent; return mParent; } } Loading libs/hwui/LayerRenderer.cpp +16 −1 Original line number Original line Diff line number Diff line Loading @@ -16,8 +16,11 @@ #define LOG_TAG "OpenGLRenderer" #define LOG_TAG "OpenGLRenderer" #include <ui/Rect.h> #include "LayerRenderer.h" #include "LayerRenderer.h" #include "Properties.h" #include "Properties.h" #include "Rect.h" namespace android { namespace android { namespace uirenderer { namespace uirenderer { Loading @@ -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); LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo); #if RENDER_LAYERS_AS_REGIONS #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(); 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 #endif glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); 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); OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque); #endif } } void LayerRenderer::finish() { void LayerRenderer::finish() { Loading libs/hwui/OpenGLRenderer.cpp +31 −19 Original line number Original line Diff line number Diff line Loading @@ -671,6 +671,21 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { finishDrawTexture(); finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS #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[] = { uint32_t colors[] = { 0x7fff0000, 0x7f00ff00, 0x7fff0000, 0x7f00ff00, 0x7f0000ff, 0x7fff00ff, 0x7f0000ff, 0x7fff00ff, Loading @@ -678,7 +693,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { int offset = 0; int offset = 0; int32_t top = rects[0].top; int32_t top = rects[0].top; int i = 0; for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) { if (top != rects[i].top) { if (top != rects[i].top) { Loading @@ -691,12 +705,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { SkXfermode::kSrcOver_Mode); SkXfermode::kSrcOver_Mode); } } #endif #endif layer->region.clear(); } #else composeLayerRect(layer, rect); #endif } } void OpenGLRenderer::dirtyLayer(const float left, const float top, void OpenGLRenderer::dirtyLayer(const float left, const float top, Loading Loading @@ -1626,6 +1634,10 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { GL_UNSIGNED_SHORT, layer->meshIndices); GL_UNSIGNED_SHORT, layer->meshIndices); finishDrawTexture(); finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS drawRegionRects(layer->region); #endif } } } } #else #else Loading libs/hwui/OpenGLRenderer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -455,6 +455,8 @@ private: void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void finishDrawTexture(); void finishDrawTexture(); void drawRegionRects(const Region& region); /** /** * Should be invoked every time the glScissor is modified. * Should be invoked every time the glScissor is modified. */ */ Loading Loading
core/java/android/view/View.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -73,7 +73,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.WeakHashMap; import java.util.WeakHashMap; /** /** Loading Loading @@ -2375,6 +2374,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility }) }) int mLayerType = LAYER_TYPE_NONE; int mLayerType = LAYER_TYPE_NONE; Paint mLayerPaint; Paint mLayerPaint; Rect mLocalDirtyRect; /** /** * Simple constructor to use when creating a view from code. * Simple constructor to use when creating a view from code. Loading Loading @@ -8173,7 +8173,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } mLayerType = layerType; 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(); invalidateParentCaches(); invalidate(true); invalidate(true); Loading Loading @@ -8228,8 +8230,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mAttachInfo.mHardwareCanvas = canvas; mAttachInfo.mHardwareCanvas = canvas; try { try { canvas.setViewport(width, height); canvas.setViewport(width, height); // TODO: We should pass the dirty rect canvas.onPreDraw(mLocalDirtyRect); canvas.onPreDraw(null); final int restoreCount = canvas.save(); final int restoreCount = canvas.save(); Loading @@ -8251,6 +8252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility canvas.onPostDraw(); canvas.onPostDraw(); mHardwareLayer.end(currentCanvas); mHardwareLayer.end(currentCanvas); mAttachInfo.mHardwareCanvas = currentCanvas; mAttachInfo.mHardwareCanvas = currentCanvas; mLocalDirtyRect.setEmpty(); } } } } Loading
core/java/android/view/ViewGroup.java +20 −8 Original line number Original line Diff line number Diff line Loading @@ -3487,17 +3487,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.mLayerType != LAYER_TYPE_NONE) { if (child.mLayerType != LAYER_TYPE_NONE) { mPrivateFlags |= INVALIDATED; mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags &= ~DRAWING_CACHE_VALID; child.mLocalDirtyRect.setEmpty(); } } do { do { View view = null; View view = null; if (parent instanceof View) { if (parent instanceof View) { view = (View) parent; view = (View) parent; if (view.mLayerType != LAYER_TYPE_NONE && if (view.mLayerType != LAYER_TYPE_NONE) { view.getParent() instanceof View) { view.mLocalDirtyRect.setEmpty(); if (view.getParent() instanceof View) { final View grandParent = (View) view.getParent(); final View grandParent = (View) view.getParent(); grandParent.mPrivateFlags |= INVALIDATED; grandParent.mPrivateFlags |= INVALIDATED; grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; } } } if ((view.mPrivateFlags & DIRTY_MASK) != 0) { if ((view.mPrivateFlags & DIRTY_MASK) != 0) { // already marked dirty - we're done // already marked dirty - we're done break; break; Loading Loading @@ -3550,7 +3553,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.mLayerType != LAYER_TYPE_NONE) { if (child.mLayerType != LAYER_TYPE_NONE) { mPrivateFlags |= INVALIDATED; mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags &= ~DRAWING_CACHE_VALID; child.mLocalDirtyRect.union(dirty); } } do { do { View view = null; View view = null; if (parent instanceof View) { if (parent instanceof View) { Loading Loading @@ -3631,6 +3636,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = left; location[CHILD_LEFT_INDEX] = left; location[CHILD_TOP_INDEX] = top; location[CHILD_TOP_INDEX] = top; if (mLayerType != LAYER_TYPE_NONE) { mLocalDirtyRect.union(dirty); } return mParent; return mParent; } } } else { } else { Loading @@ -3639,8 +3648,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_TOP_INDEX] = mTop; location[CHILD_TOP_INDEX] = mTop; dirty.set(0, 0, mRight - location[CHILD_LEFT_INDEX], dirty.set(0, 0, mRight - mLeft, mBottom - mTop); mBottom - location[CHILD_TOP_INDEX]); if (mLayerType != LAYER_TYPE_NONE) { mLocalDirtyRect.union(dirty); } return mParent; return mParent; } } Loading
libs/hwui/LayerRenderer.cpp +16 −1 Original line number Original line Diff line number Diff line Loading @@ -16,8 +16,11 @@ #define LOG_TAG "OpenGLRenderer" #define LOG_TAG "OpenGLRenderer" #include <ui/Rect.h> #include "LayerRenderer.h" #include "LayerRenderer.h" #include "Properties.h" #include "Properties.h" #include "Rect.h" namespace android { namespace android { namespace uirenderer { namespace uirenderer { Loading @@ -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); LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo); #if RENDER_LAYERS_AS_REGIONS #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(); 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 #endif glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); 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); OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque); #endif } } void LayerRenderer::finish() { void LayerRenderer::finish() { Loading
libs/hwui/OpenGLRenderer.cpp +31 −19 Original line number Original line Diff line number Diff line Loading @@ -671,6 +671,21 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { finishDrawTexture(); finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS #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[] = { uint32_t colors[] = { 0x7fff0000, 0x7f00ff00, 0x7fff0000, 0x7f00ff00, 0x7f0000ff, 0x7fff00ff, 0x7f0000ff, 0x7fff00ff, Loading @@ -678,7 +693,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { int offset = 0; int offset = 0; int32_t top = rects[0].top; int32_t top = rects[0].top; int i = 0; for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) { if (top != rects[i].top) { if (top != rects[i].top) { Loading @@ -691,12 +705,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { SkXfermode::kSrcOver_Mode); SkXfermode::kSrcOver_Mode); } } #endif #endif layer->region.clear(); } #else composeLayerRect(layer, rect); #endif } } void OpenGLRenderer::dirtyLayer(const float left, const float top, void OpenGLRenderer::dirtyLayer(const float left, const float top, Loading Loading @@ -1626,6 +1634,10 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { GL_UNSIGNED_SHORT, layer->meshIndices); GL_UNSIGNED_SHORT, layer->meshIndices); finishDrawTexture(); finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS drawRegionRects(layer->region); #endif } } } } #else #else Loading
libs/hwui/OpenGLRenderer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -455,6 +455,8 @@ private: void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void finishDrawTexture(); void finishDrawTexture(); void drawRegionRects(const Region& region); /** /** * Should be invoked every time the glScissor is modified. * Should be invoked every time the glScissor is modified. */ */ Loading