Loading core/jni/android_view_GLES20Canvas.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject cl static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) { return renderer->quickReject(left, top, right, bottom); return renderer->quickRejectNoScissor(left, top, right, bottom); } static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, Loading libs/hwui/DisplayList.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -356,22 +356,26 @@ void DisplayList::outputViewProperties(const int level) { level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix)); } } bool clipToBoundsNeeded = mClipToBounds; if (mAlpha < 1) { if (mCaching) { ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha); clipToBoundsNeeded = false; // clipping done by layer } else if (!mHasOverlappingRendering) { ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha); } else { int flags = SkCanvas::kHasAlphaLayer_SaveFlag; if (mClipToBounds) { if (clipToBoundsNeeded) { flags |= SkCanvas::kClipToLayer_SaveFlag; clipToBoundsNeeded = false; // clipping done by save layer } ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "", (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, (int)(mAlpha * 255), flags); } } if (mClipToBounds && !mCaching) { if (clipToBoundsNeeded) { ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f, (float) mRight - mLeft, (float) mBottom - mTop); } Loading Loading @@ -406,9 +410,11 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, renderer.concatMatrix(mTransformMatrix); } } bool clipToBoundsNeeded = mClipToBounds; if (mAlpha < 1) { if (mCaching) { renderer.setOverrideLayerAlpha(mAlpha); clipToBoundsNeeded = false; // clipping done by layer } else if (!mHasOverlappingRendering) { renderer.scaleAlpha(mAlpha); } else { Loading @@ -416,15 +422,16 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, // have to pass it into this call. In fact, this information might be in the // location/size info that we store with the new native transform data. int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag; if (mClipToBounds) { if (clipToBoundsNeeded) { saveFlags |= SkCanvas::kClipToLayer_SaveFlag; clipToBoundsNeeded = false; // clipping done by saveLayer } handler(mSaveLayerOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags), PROPERTY_SAVECOUNT, mClipToBounds); } } if (mClipToBounds && !mCaching) { if (clipToBoundsNeeded) { handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op), PROPERTY_SAVECOUNT, mClipToBounds); } Loading libs/hwui/OpenGLRenderer.cpp +26 −35 Original line number Diff line number Diff line Loading @@ -993,6 +993,10 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const Rect& rect = layer->layer; const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { endTiling(); Loading Loading @@ -1568,8 +1572,9 @@ const Rect& OpenGLRenderer::getClipBounds() { return mSnapshot->getLocalClip(); } bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom) { if (mSnapshot->isIgnored()) { bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, bool* clipRequired) { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; } Loading @@ -1580,23 +1585,10 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl Rect clipRect(*mSnapshot->clipRect); clipRect.snapToPixelBoundaries(); return !clipRect.intersects(r); } bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, Rect& transformed, Rect& clip) { if (mSnapshot->isIgnored()) { return true; } transformed.set(left, top, right, bottom); currentTransform().mapRect(transformed); transformed.snapToPixelBoundaries(); clip.set(*mSnapshot->clipRect); clip.snapToPixelBoundaries(); if (!clipRect.intersects(r)) return true; return !clip.intersects(transformed); if (clipRequired) *clipRequired = !clipRect.contains(r); return false; } bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom, Loading @@ -1610,23 +1602,15 @@ bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, fl } bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { bool clipRequired = false; if (quickRejectNoScissor(left, top, right, bottom, &clipRequired)) { return true; } Rect r(left, top, right, bottom); currentTransform().mapRect(r); r.snapToPixelBoundaries(); Rect clipRect(*mSnapshot->clipRect); clipRect.snapToPixelBoundaries(); bool rejected = !clipRect.intersects(r); if (!isDeferred() && !rejected) { mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r)); if (!isDeferred()) { mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); } return rejected; return false; } void OpenGLRenderer::debugClip() { Loading Loading @@ -2163,6 +2147,9 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes return DrawGlInfo::kStatusDone; } // TODO: use quickReject on bounds from vertices mCaches.enableScissor(); float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; Loading Loading @@ -2829,6 +2816,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count return DrawGlInfo::kStatusDone; } mCaches.enableScissor(); float x = 0.0f; float y = 0.0f; const bool pureTranslate = currentTransform().isPureTranslate(); Loading Loading @@ -2984,6 +2973,9 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co return DrawGlInfo::kStatusDone; } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics mCaches.enableScissor(); FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); fontRenderer.setFont(paint, mat4::identity()); fontRenderer.setTextureFiltering(true); Loading Loading @@ -3059,10 +3051,9 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } } Rect transformed; Rect clip; bool clipRequired = false; const bool rejected = quickRejectNoScissor(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip); x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired); if (rejected) { if (transform && !transform->isIdentity()) { Loading @@ -3073,7 +3064,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { updateLayer(layer, true); mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed)); mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); mCaches.activeTexture(0); if (CC_LIKELY(!layer->region.isEmpty())) { Loading libs/hwui/OpenGLRenderer.h +22 −14 Original line number Diff line number Diff line Loading @@ -252,11 +252,31 @@ public: virtual void concatMatrix(SkMatrix* matrix); ANDROID_API const Rect& getClipBounds(); ANDROID_API bool quickReject(float left, float top, float right, float bottom); /** * Performs a quick reject but adjust the bounds to account for stroke width if necessary */ bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint); /** * Returns false and sets scissor based upon bounds if drawing won't be clipped out */ bool quickReject(float left, float top, float right, float bottom); bool quickReject(const Rect& bounds) { return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom); } bool quickRejectNoScissor(float left, float top, float right, float bottom); /** * Same as quickReject, without the scissor, instead returning clipRequired through pointer. * clipRequired will be only set if not rejected */ ANDROID_API bool quickRejectNoScissor(float left, float top, float right, float bottom, bool* clipRequired = NULL); bool quickRejectNoScissor(const Rect& bounds, bool* clipRequired = NULL) { return quickRejectNoScissor(bounds.left, bounds.top, bounds.right, bounds.bottom, clipRequired); } virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); virtual bool clipPath(SkPath* path, SkRegion::Op op); virtual bool clipRegion(SkRegion* region, SkRegion::Op op); Loading Loading @@ -603,18 +623,6 @@ private: */ void setStencilFromClip(); /** * Performs a quick reject but does not affect the scissor. Returns * the transformed rect to test and the current clip. */ bool quickRejectNoScissor(float left, float top, float right, float bottom, Rect& transformed, Rect& clip); /** * Performs a quick reject but adjust the bounds to account for stroke width if necessary */ bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint); /** * Given the local bounds of the layer, calculates ... */ Loading libs/hwui/Rect.h +1 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ namespace android { namespace uirenderer { #define RECT_STRING "%4.2f %4.2f %4.2f %4.2f" #define RECT_STRING "%7.2f %7.2f %7.2f %7.2f" #define RECT_ARGS(r) \ (r).left, (r).top, (r).right, (r).bottom Loading Loading
core/jni/android_view_GLES20Canvas.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject cl static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) { return renderer->quickReject(left, top, right, bottom); return renderer->quickRejectNoScissor(left, top, right, bottom); } static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, Loading
libs/hwui/DisplayList.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -356,22 +356,26 @@ void DisplayList::outputViewProperties(const int level) { level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix)); } } bool clipToBoundsNeeded = mClipToBounds; if (mAlpha < 1) { if (mCaching) { ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha); clipToBoundsNeeded = false; // clipping done by layer } else if (!mHasOverlappingRendering) { ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha); } else { int flags = SkCanvas::kHasAlphaLayer_SaveFlag; if (mClipToBounds) { if (clipToBoundsNeeded) { flags |= SkCanvas::kClipToLayer_SaveFlag; clipToBoundsNeeded = false; // clipping done by save layer } ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "", (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, (int)(mAlpha * 255), flags); } } if (mClipToBounds && !mCaching) { if (clipToBoundsNeeded) { ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f, (float) mRight - mLeft, (float) mBottom - mTop); } Loading Loading @@ -406,9 +410,11 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, renderer.concatMatrix(mTransformMatrix); } } bool clipToBoundsNeeded = mClipToBounds; if (mAlpha < 1) { if (mCaching) { renderer.setOverrideLayerAlpha(mAlpha); clipToBoundsNeeded = false; // clipping done by layer } else if (!mHasOverlappingRendering) { renderer.scaleAlpha(mAlpha); } else { Loading @@ -416,15 +422,16 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, // have to pass it into this call. In fact, this information might be in the // location/size info that we store with the new native transform data. int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag; if (mClipToBounds) { if (clipToBoundsNeeded) { saveFlags |= SkCanvas::kClipToLayer_SaveFlag; clipToBoundsNeeded = false; // clipping done by saveLayer } handler(mSaveLayerOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags), PROPERTY_SAVECOUNT, mClipToBounds); } } if (mClipToBounds && !mCaching) { if (clipToBoundsNeeded) { handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op), PROPERTY_SAVECOUNT, mClipToBounds); } Loading
libs/hwui/OpenGLRenderer.cpp +26 −35 Original line number Diff line number Diff line Loading @@ -993,6 +993,10 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const Rect& rect = layer->layer; const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer; bool clipRequired = false; quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { endTiling(); Loading Loading @@ -1568,8 +1572,9 @@ const Rect& OpenGLRenderer::getClipBounds() { return mSnapshot->getLocalClip(); } bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom) { if (mSnapshot->isIgnored()) { bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, bool* clipRequired) { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { return true; } Loading @@ -1580,23 +1585,10 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl Rect clipRect(*mSnapshot->clipRect); clipRect.snapToPixelBoundaries(); return !clipRect.intersects(r); } bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom, Rect& transformed, Rect& clip) { if (mSnapshot->isIgnored()) { return true; } transformed.set(left, top, right, bottom); currentTransform().mapRect(transformed); transformed.snapToPixelBoundaries(); clip.set(*mSnapshot->clipRect); clip.snapToPixelBoundaries(); if (!clipRect.intersects(r)) return true; return !clip.intersects(transformed); if (clipRequired) *clipRequired = !clipRect.contains(r); return false; } bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom, Loading @@ -1610,23 +1602,15 @@ bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, fl } bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { if (mSnapshot->isIgnored() || bottom <= top || right <= left) { bool clipRequired = false; if (quickRejectNoScissor(left, top, right, bottom, &clipRequired)) { return true; } Rect r(left, top, right, bottom); currentTransform().mapRect(r); r.snapToPixelBoundaries(); Rect clipRect(*mSnapshot->clipRect); clipRect.snapToPixelBoundaries(); bool rejected = !clipRect.intersects(r); if (!isDeferred() && !rejected) { mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r)); if (!isDeferred()) { mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); } return rejected; return false; } void OpenGLRenderer::debugClip() { Loading Loading @@ -2163,6 +2147,9 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes return DrawGlInfo::kStatusDone; } // TODO: use quickReject on bounds from vertices mCaches.enableScissor(); float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; Loading Loading @@ -2829,6 +2816,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count return DrawGlInfo::kStatusDone; } mCaches.enableScissor(); float x = 0.0f; float y = 0.0f; const bool pureTranslate = currentTransform().isPureTranslate(); Loading Loading @@ -2984,6 +2973,9 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co return DrawGlInfo::kStatusDone; } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics mCaches.enableScissor(); FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); fontRenderer.setFont(paint, mat4::identity()); fontRenderer.setTextureFiltering(true); Loading Loading @@ -3059,10 +3051,9 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { } } Rect transformed; Rect clip; bool clipRequired = false; const bool rejected = quickRejectNoScissor(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip); x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired); if (rejected) { if (transform && !transform->isIdentity()) { Loading @@ -3073,7 +3064,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { updateLayer(layer, true); mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed)); mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); mCaches.activeTexture(0); if (CC_LIKELY(!layer->region.isEmpty())) { Loading
libs/hwui/OpenGLRenderer.h +22 −14 Original line number Diff line number Diff line Loading @@ -252,11 +252,31 @@ public: virtual void concatMatrix(SkMatrix* matrix); ANDROID_API const Rect& getClipBounds(); ANDROID_API bool quickReject(float left, float top, float right, float bottom); /** * Performs a quick reject but adjust the bounds to account for stroke width if necessary */ bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint); /** * Returns false and sets scissor based upon bounds if drawing won't be clipped out */ bool quickReject(float left, float top, float right, float bottom); bool quickReject(const Rect& bounds) { return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom); } bool quickRejectNoScissor(float left, float top, float right, float bottom); /** * Same as quickReject, without the scissor, instead returning clipRequired through pointer. * clipRequired will be only set if not rejected */ ANDROID_API bool quickRejectNoScissor(float left, float top, float right, float bottom, bool* clipRequired = NULL); bool quickRejectNoScissor(const Rect& bounds, bool* clipRequired = NULL) { return quickRejectNoScissor(bounds.left, bounds.top, bounds.right, bounds.bottom, clipRequired); } virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); virtual bool clipPath(SkPath* path, SkRegion::Op op); virtual bool clipRegion(SkRegion* region, SkRegion::Op op); Loading Loading @@ -603,18 +623,6 @@ private: */ void setStencilFromClip(); /** * Performs a quick reject but does not affect the scissor. Returns * the transformed rect to test and the current clip. */ bool quickRejectNoScissor(float left, float top, float right, float bottom, Rect& transformed, Rect& clip); /** * Performs a quick reject but adjust the bounds to account for stroke width if necessary */ bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint); /** * Given the local bounds of the layer, calculates ... */ Loading
libs/hwui/Rect.h +1 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ namespace android { namespace uirenderer { #define RECT_STRING "%4.2f %4.2f %4.2f %4.2f" #define RECT_STRING "%7.2f %7.2f %7.2f %7.2f" #define RECT_ARGS(r) \ (r).left, (r).top, (r).right, (r).bottom Loading