diff options
author | Chris Craik <ccraik@google.com> | 2015-05-28 22:03:06 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-05-28 22:03:08 +0000 |
commit | 1cd7e4c3d0216cfb9a8a685ca8cf6f0d740a9dff (patch) | |
tree | 2ae1662b8d6a4ff711e6ce621e690e4f6204c0f1 /libs/hwui/OpenGLRenderer.cpp | |
parent | 5cd795a9094eb02c983751ecabca6f24b0a01c58 (diff) | |
parent | fca52b7583d1e5f5ff8ed06554875d2a30ef56fa (diff) | |
download | frameworks_base-1cd7e4c3d0216cfb9a8a685ca8cf6f0d740a9dff.zip frameworks_base-1cd7e4c3d0216cfb9a8a685ca8cf6f0d740a9dff.tar.gz frameworks_base-1cd7e4c3d0216cfb9a8a685ca8cf6f0d740a9dff.tar.bz2 |
Merge "Use path intersection instead of saveLayer+mesh to mask projected ripples" into mnc-dev
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index b3fb7ef..8f91620 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -40,6 +40,7 @@ #include <SkCanvas.h> #include <SkColor.h> +#include <SkPathOps.h> #include <SkShader.h> #include <SkTypeface.h> @@ -1193,8 +1194,9 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef state.mMatrix.load(*currentMatrix); state.mAlpha = currentSnapshot()->alpha; - // always store/restore, since it's just a pointer + // always store/restore, since these are just pointers state.mRoundRectClipState = currentSnapshot()->roundRectClipState; + state.mProjectionPathMask = currentSnapshot()->projectionPathMask; return false; } @@ -1202,6 +1204,7 @@ void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool setMatrix(state.mMatrix); writableSnapshot()->alpha = state.mAlpha; writableSnapshot()->roundRectClipState = state.mRoundRectClipState; + writableSnapshot()->projectionPathMask = state.mProjectionPathMask; if (state.mClipValid && !skipClipRestore) { writableSnapshot()->setClip(state.mClip.left, state.mClip.top, @@ -1758,6 +1761,7 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) { VertexBuffer vertexBuffer; // TODO: try clipping large paths to viewport + PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer); drawVertexBuffer(vertexBuffer, paint); } @@ -1864,19 +1868,41 @@ void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p || PaintUtils::paintWillNotDraw(*p)) { return; } + if (p->getPathEffect() != nullptr) { mCaches.textureState().activateTexture(0); PathTexture* texture = mCaches.pathCache.getCircle(radius, p); drawShape(x - radius, y - radius, texture, p); + return; + } + + SkPath path; + if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { + path.addCircle(x, y, radius + p->getStrokeWidth() / 2); } else { - SkPath path; - if (p->getStyle() == SkPaint::kStrokeAndFill_Style) { - path.addCircle(x, y, radius + p->getStrokeWidth() / 2); - } else { - path.addCircle(x, y, radius); - } - drawConvexPath(path, p); + path.addCircle(x, y, radius); + } + + if (CC_UNLIKELY(currentSnapshot()->projectionPathMask != nullptr)) { + // mask ripples with projection mask + SkPath maskPath = *(currentSnapshot()->projectionPathMask->projectionMask); + + Matrix4 screenSpaceTransform; + currentSnapshot()->buildScreenSpaceTransform(&screenSpaceTransform); + + Matrix4 totalTransform; + totalTransform.loadInverse(screenSpaceTransform); + totalTransform.multiply(currentSnapshot()->projectionPathMask->projectionMaskTransform); + + SkMatrix skTotalTransform; + totalTransform.copyTo(skTotalTransform); + maskPath.transform(skTotalTransform); + + // Mask the ripple path by the projection mask, now that it's + // in local space. Note that this can create CCW paths. + Op(path, maskPath, kIntersect_PathOp, &path); } + drawConvexPath(path, p); } void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, @@ -2149,6 +2175,10 @@ void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator, mState.setClippingRoundRect(allocator, rect, radius, highPriority); } +void OpenGLRenderer::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) { + mState.setProjectionPathMask(allocator, path); +} + void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { |