diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 61 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 6 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 9 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 2 |
4 files changed, 45 insertions, 33 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 9dc5b45a7738..ddfd62141f5d 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -62,7 +62,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) , mJankTracker(thread.timeLord().frameIntervalNanos()) , mProfiler(mFrames) - , mContentOverdrawProtectionBounds(0, 0, 0, 0) { + , mContentDrawBounds(0, 0, 0, 0) { mRenderNodes.emplace_back(rootRenderNode); mRenderThread.renderState().registerCanvasContext(this); mProfiler.setDensity(mRenderThread.mainDisplayInfo().density); @@ -309,7 +309,7 @@ void CanvasContext::draw() { Rect outBounds; // It there are multiple render nodes, they are as follows: // #0 - backdrop - // #1 - content (with - and clipped to - bounds mContentOverdrawProtectionBounds) + // #1 - content (positioned at (0,0) and clipped to - its bounds mContentDrawBounds) // #2 - frame // Usually the backdrop cannot be seen since it will be entirely covered by the content. While // resizing however it might become partially visible. The following render loop will crop the @@ -317,66 +317,72 @@ void CanvasContext::draw() { // against the backdrop (since that indicates a shrinking of the window) and then the frame // around everything. // The bounds of the backdrop against which the content should be clipped. - Rect backdropBounds = mContentOverdrawProtectionBounds; + Rect backdropBounds = mContentDrawBounds; + // Usually the contents bounds should be mContentDrawBounds - however - we will + // move it towards the fixed edge to give it a more stable appearance (for the moment). + Rect contentBounds; // If there is no content bounds we ignore the layering as stated above and start with 2. - int layer = mContentOverdrawProtectionBounds.isEmpty() ? 2 : 0; + int layer = (mContentDrawBounds.isEmpty() || mRenderNodes.size() <= 2) ? 2 : 0; // Draw all render nodes. Note that for (const sp<RenderNode>& node : mRenderNodes) { if (layer == 0) { // Backdrop. - // Draw the backdrop clipped to the inverse content bounds. + // Draw the backdrop clipped to the inverse content bounds, but assume that the content + // was moved to the upper left corner. const RenderProperties& properties = node->properties(); Rect targetBounds(properties.getLeft(), properties.getTop(), properties.getRight(), properties.getBottom()); + // Move the content bounds towards the fixed corner of the backdrop. + const int x = targetBounds.left; + const int y = targetBounds.top; + contentBounds.set(x, y, x + mContentDrawBounds.getWidth(), + y + mContentDrawBounds.getHeight()); // Remember the intersection of the target bounds and the intersection bounds against // which we have to crop the content. + backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight()); backdropBounds.intersect(targetBounds); // Check if we have to draw something on the left side ... - if (targetBounds.left < mContentOverdrawProtectionBounds.left) { + if (targetBounds.left < contentBounds.left) { mCanvas->save(SkCanvas::kClip_SaveFlag); if (mCanvas->clipRect(targetBounds.left, targetBounds.top, - mContentOverdrawProtectionBounds.left, targetBounds.bottom, + contentBounds.left, targetBounds.bottom, SkRegion::kIntersect_Op)) { mCanvas->drawRenderNode(node.get(), outBounds); } // Reduce the target area by the area we have just painted. - targetBounds.left = std::min(mContentOverdrawProtectionBounds.left, - targetBounds.right); + targetBounds.left = std::min(contentBounds.left, targetBounds.right); mCanvas->restore(); } // ... or on the right side ... - if (targetBounds.right > mContentOverdrawProtectionBounds.right && + if (targetBounds.right > contentBounds.right && !targetBounds.isEmpty()) { mCanvas->save(SkCanvas::kClip_SaveFlag); - if (mCanvas->clipRect(mContentOverdrawProtectionBounds.right, targetBounds.top, + if (mCanvas->clipRect(contentBounds.right, targetBounds.top, targetBounds.right, targetBounds.bottom, SkRegion::kIntersect_Op)) { mCanvas->drawRenderNode(node.get(), outBounds); } // Reduce the target area by the area we have just painted. - targetBounds.right = std::max(targetBounds.left, - mContentOverdrawProtectionBounds.right); + targetBounds.right = std::max(targetBounds.left, contentBounds.right); mCanvas->restore(); } // ... or at the top ... - if (targetBounds.top < mContentOverdrawProtectionBounds.top && + if (targetBounds.top < contentBounds.top && !targetBounds.isEmpty()) { mCanvas->save(SkCanvas::kClip_SaveFlag); if (mCanvas->clipRect(targetBounds.left, targetBounds.top, targetBounds.right, - mContentOverdrawProtectionBounds.top, + contentBounds.top, SkRegion::kIntersect_Op)) { mCanvas->drawRenderNode(node.get(), outBounds); } // Reduce the target area by the area we have just painted. - targetBounds.top = std::min(mContentOverdrawProtectionBounds.top, - targetBounds.bottom); + targetBounds.top = std::min(contentBounds.top, targetBounds.bottom); mCanvas->restore(); } // ... or at the bottom. - if (targetBounds.bottom > mContentOverdrawProtectionBounds.bottom && + if (targetBounds.bottom > contentBounds.bottom && !targetBounds.isEmpty()) { mCanvas->save(SkCanvas::kClip_SaveFlag); - if (mCanvas->clipRect(targetBounds.left, - mContentOverdrawProtectionBounds.bottom, targetBounds.right, + if (mCanvas->clipRect(targetBounds.left, contentBounds.bottom, targetBounds.right, targetBounds.bottom, SkRegion::kIntersect_Op)) { mCanvas->drawRenderNode(node.get(), outBounds); } @@ -384,10 +390,17 @@ void CanvasContext::draw() { } } else if (layer == 1) { // Content // It gets cropped against the bounds of the backdrop to stay inside. - mCanvas->save(SkCanvas::kClip_SaveFlag); - if (mCanvas->clipRect(backdropBounds.left, backdropBounds.top, - backdropBounds.right, backdropBounds.bottom, - SkRegion::kIntersect_Op)) { + mCanvas->save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag); + + // We shift and clip the content to match its final location in the window. + const float left = mContentDrawBounds.left; + const float top = mContentDrawBounds.top; + const float dx = backdropBounds.left - left; + const float dy = backdropBounds.top - top; + const float width = backdropBounds.getWidth(); + const float height = backdropBounds.getHeight(); + mCanvas->translate(dx, dy); + if (mCanvas->clipRect(left, top, left + width, top + height, SkRegion::kIntersect_Op)) { mCanvas->drawRenderNode(node.get(), outBounds); } mCanvas->restore(); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 1c3845cac504..e0cbabdc933a 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -126,8 +126,8 @@ public: mRenderNodes.end()); } - void setContentOverdrawProtectionBounds(int left, int top, int right, int bottom) { - mContentOverdrawProtectionBounds.set(left, top, right, bottom); + void setContentDrawBounds(int left, int top, int right, int bottom) { + mContentDrawBounds.set(left, top, right, bottom); } private: @@ -167,7 +167,7 @@ private: std::set<RenderNode*> mPrefetechedLayers; // Stores the bounds of the main content. - Rect mContentOverdrawProtectionBounds; + Rect mContentDrawBounds; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index f43a769890a4..26aae90d5990 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -529,15 +529,14 @@ void RenderProxy::drawRenderNode(RenderNode* node) { staticPostAndWait(task); } -CREATE_BRIDGE5(setContentOverdrawProtectionBounds, CanvasContext* context, int left, int top, +CREATE_BRIDGE5(setContentDrawBounds, CanvasContext* context, int left, int top, int right, int bottom) { - args->context->setContentOverdrawProtectionBounds(args->left, args->top, args->right, - args->bottom); + args->context->setContentDrawBounds(args->left, args->top, args->right, args->bottom); return nullptr; } -void RenderProxy::setContentOverdrawProtectionBounds(int left, int top, int right, int bottom) { - SETUP_TASK(setContentOverdrawProtectionBounds); +void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) { + SETUP_TASK(setContentDrawBounds); args->context = mContext; args->left = left; args->top = top; diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 046f24ac3f81..d1b62f1f64a6 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -109,7 +109,7 @@ public: ANDROID_API void addRenderNode(RenderNode* node, bool placeFront); ANDROID_API void removeRenderNode(RenderNode* node); ANDROID_API void drawRenderNode(RenderNode* node); - ANDROID_API void setContentOverdrawProtectionBounds(int left, int top, int right, int bottom); + ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom); private: RenderThread& mRenderThread; |