diff options
author | Stan Iliev <stani@google.com> | 2017-08-01 18:51:37 -0400 |
---|---|---|
committer | Stan Iliev <stani@google.com> | 2017-08-02 16:05:11 -0400 |
commit | 6a3b0553d94701d91f1923bfb863a79bbf427893 (patch) | |
tree | 0673519e70580c0a87afd7f4374976b4714fd882 /libs/hwui/pipeline/skia/GLFunctorDrawable.cpp | |
parent | 1af947ef11e0c359f460c361f964a88158f5db32 (diff) |
Implement efficiently non-rectangular clips in GLFunctorDrawable
Implement non-rectangular clips by writing into the stencil
buffer using new Skia API. This CL is fixing
PathClippingTests#testWebViewClipWithCircle test, which was
failing on some devices.
Bug: 34454070
Bug: 31489986
Test: CtsUiRenderingTestCases tests passed for Skia pipeline.
Change-Id: I29d7af02e2af53943540a91393f5d7a8c4e44049
Diffstat (limited to 'libs/hwui/pipeline/skia/GLFunctorDrawable.cpp')
-rw-r--r-- | libs/hwui/pipeline/skia/GLFunctorDrawable.cpp | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp index ea302a154616..fcd72afe4fb9 100644 --- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp @@ -17,6 +17,7 @@ #include "GLFunctorDrawable.h" #include "GlFunctorLifecycleListener.h" #include "RenderNode.h" +#include "SkAndroidFrameworkUtils.h" #include "SkClipStack.h" #include <private/hwui/DrawGlInfo.h> #include <GrContext.h> @@ -49,8 +50,6 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { return; } - canvas->flush(); - if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { canvas->clear(SK_ColorRED); return; @@ -72,33 +71,33 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { info.height = canvasInfo.height(); mat4.asColMajorf(&info.transform[0]); + bool clearStencilAfterFunctor = false; + //apply a simple clip with a scissor or a complex clip with a stencil SkRegion clipRegion; canvas->temporary_internal_getRgnClip(&clipRegion); if (CC_UNLIKELY(clipRegion.isComplex())) { - //It is only a temporary solution to use a scissor to draw the stencil. - //There is a bug 31489986 to implement efficiently non-rectangular clips. glDisable(GL_SCISSOR_TEST); - glDisable(GL_STENCIL_TEST); - glStencilMask(0xff); + glStencilMask(0x1); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - SkRegion::Cliperator it(clipRegion, ibounds); - while (!it.done()) { - setScissor(info.height, it.rect()); - glClearStencil(0x1); - glClear(GL_STENCIL_BUFFER_BIT); - it.next(); + bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(canvas); + canvas->flush(); + if (stencilWritten) { + glStencilMask(0x1); + glStencilFunc(GL_EQUAL, 0x1, 0x1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + clearStencilAfterFunctor = true; + glEnable(GL_STENCIL_TEST); + } else { + glDisable(GL_STENCIL_TEST); } - glDisable(GL_SCISSOR_TEST); - glStencilFunc(GL_EQUAL, 0x1, 0xff); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glEnable(GL_STENCIL_TEST); } else if (clipRegion.isEmpty()) { + canvas->flush(); glDisable(GL_STENCIL_TEST); glDisable(GL_SCISSOR_TEST); } else { + canvas->flush(); glDisable(GL_STENCIL_TEST); glEnable(GL_SCISSOR_TEST); setScissor(info.height, clipRegion.getBounds()); @@ -106,6 +105,15 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { (*mFunctor)(DrawGlInfo::kModeDraw, &info); + if (clearStencilAfterFunctor) { + //clear stencil buffer as it may be used by Skia + glDisable(GL_SCISSOR_TEST); + glDisable(GL_STENCIL_TEST); + glStencilMask(0x1); + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + } + canvas->getGrContext()->resetContext(); } |