diff options
| author | Romain Guy <romainguy@google.com> | 2012-08-31 20:31:01 -0700 |
|---|---|---|
| committer | Romain Guy <romainguy@google.com> | 2012-08-31 20:31:32 -0700 |
| commit | 0baaac5e9adf3ee280ae1239e2e58754a9d2b099 (patch) | |
| tree | 430a7392973ff3dc04089cc2b3550afcdde673de | |
| parent | a8557d2169e14997637f57bc897640c8882d4a46 (diff) | |
| download | frameworks_base-0baaac5e9adf3ee280ae1239e2e58754a9d2b099.zip frameworks_base-0baaac5e9adf3ee280ae1239e2e58754a9d2b099.tar.gz frameworks_base-0baaac5e9adf3ee280ae1239e2e58754a9d2b099.tar.bz2 | |
Revert "Revert "Add more support for transformed clip rects and paths""
This reverts commit a8557d2169e14997637f57bc897640c8882d4a46.
Change-Id: I36d4883d548fc47ba6c0b4a42012107d0d2f85a6
| -rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 3 | ||||
| -rw-r--r-- | libs/hwui/Android.mk | 1 | ||||
| -rw-r--r-- | libs/hwui/Caches.h | 7 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 6 | ||||
| -rw-r--r-- | libs/hwui/Snapshot.cpp | 76 | ||||
| -rw-r--r-- | libs/hwui/Snapshot.h | 9 | ||||
| -rw-r--r-- | libs/hwui/Stencil.cpp | 71 | ||||
| -rw-r--r-- | libs/hwui/Stencil.h | 89 |
9 files changed, 189 insertions, 77 deletions
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 9fc73a4..3538fef 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -46,6 +46,7 @@ #include <OpenGLRenderer.h> #include <SkiaShader.h> #include <SkiaColorFilter.h> +#include <Stencil.h> #include <Rect.h> #include <TextLayout.h> @@ -150,7 +151,7 @@ static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz, } static jint android_view_GLES20Canvas_getStencilSize(JNIEnv* env, jobject clazz) { - return OpenGLRenderer::getStencilSize(); + return Stencil::getStencilSize(); } // ---------------------------------------------------------------------------- diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 1947c32..c3a07a1 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -28,6 +28,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) SkiaColorFilter.cpp \ SkiaShader.cpp \ Snapshot.cpp \ + Stencil.cpp \ TextureCache.cpp \ TextDropShadowCache.cpp diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index f4f56d6..b9a6336 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -38,6 +38,7 @@ #include "TextDropShadowCache.h" #include "FboCache.h" #include "ResourceCache.h" +#include "Stencil.h" #include "Dither.h" namespace android { @@ -252,10 +253,14 @@ public: TextDropShadowCache dropShadowCache; FboCache fboCache; ResourceCache resourceCache; - Dither dither; GammaFontRenderer* fontRenderer; + Dither dither; +#if STENCIL_BUFFER_SIZE + Stencil stencil; +#endif + // Debug methods PFNGLINSERTEVENTMARKEREXTPROC eventMark; PFNGLPUSHGROUPMARKEREXTPROC startMark; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 8da9f66..2f43be8 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -139,10 +139,6 @@ void OpenGLRenderer::endMark() const { // Setup /////////////////////////////////////////////////////////////////////////////// -uint32_t OpenGLRenderer::getStencilSize() { - return STENCIL_BUFFER_SIZE; -} - bool OpenGLRenderer::isDeferred() { return false; } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 2369f47..4c7cf0a 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -208,12 +208,6 @@ public: SkPaint* filterPaint(SkPaint* paint); /** - * Returns the desired size for the stencil buffer. If the returned value - * is 0, then no stencil buffer is required. - */ - ANDROID_API static uint32_t getStencilSize(); - - /** * Sets the alpha on the current snapshot. This alpha value will be modulated * with other alpha values when drawing primitives. */ diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index 5d5961a..4484676 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -57,7 +57,7 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): clipRect = &mClipRectRoot; #if STENCIL_BUFFER_SIZE if (s->clipRegion) { - mClipRegionRoot.merge(*s->clipRegion); + mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op); clipRegion = &mClipRegionRoot; } #endif @@ -84,8 +84,7 @@ void Snapshot::ensureClipRegion() { #if STENCIL_BUFFER_SIZE if (!clipRegion) { clipRegion = &mClipRegionRoot; - android::Rect tmp(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); - clipRegion->set(tmp); + clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); } #endif } @@ -93,11 +92,11 @@ void Snapshot::ensureClipRegion() { void Snapshot::copyClipRectFromRegion() { #if STENCIL_BUFFER_SIZE if (!clipRegion->isEmpty()) { - android::Rect bounds(clipRegion->bounds()); - clipRect->set(bounds.left, bounds.top, bounds.right, bounds.bottom); + const SkIRect& bounds = clipRegion->getBounds(); + clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); if (clipRegion->isRect()) { - clipRegion->clear(); + clipRegion->setEmpty(); clipRegion = NULL; } } else { @@ -107,43 +106,11 @@ void Snapshot::copyClipRectFromRegion() { #endif } -bool Snapshot::clipRegionOr(float left, float top, float right, float bottom) { +bool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) { #if STENCIL_BUFFER_SIZE - android::Rect tmp(left, top, right, bottom); - clipRegion->orSelf(tmp); - copyClipRectFromRegion(); - return true; -#else - return false; -#endif -} - -bool Snapshot::clipRegionXor(float left, float top, float right, float bottom) { -#if STENCIL_BUFFER_SIZE - android::Rect tmp(left, top, right, bottom); - clipRegion->xorSelf(tmp); - copyClipRectFromRegion(); - return true; -#else - return false; -#endif -} - -bool Snapshot::clipRegionAnd(float left, float top, float right, float bottom) { -#if STENCIL_BUFFER_SIZE - android::Rect tmp(left, top, right, bottom); - clipRegion->andSelf(tmp); - copyClipRectFromRegion(); - return true; -#else - return false; -#endif -} - -bool Snapshot::clipRegionNand(float left, float top, float right, float bottom) { -#if STENCIL_BUFFER_SIZE - android::Rect tmp(left, top, right, bottom); - clipRegion->subtractSelf(tmp); + SkIRect tmp; + tmp.set(left, top, right, bottom); + clipRegion->op(tmp, op); copyClipRectFromRegion(); return true; #else @@ -161,14 +128,9 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { bool clipped = false; switch (op) { - case SkRegion::kDifference_Op: { - ensureClipRegion(); - clipped = clipRegionNand(r.left, r.top, r.right, r.bottom); - break; - } case SkRegion::kIntersect_Op: { if (CC_UNLIKELY(clipRegion)) { - clipped = clipRegionOr(r.left, r.top, r.right, r.bottom); + clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op); } else { clipped = clipRect->intersect(r); if (!clipped) { @@ -180,26 +142,22 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { } case SkRegion::kUnion_Op: { if (CC_UNLIKELY(clipRegion)) { - clipped = clipRegionAnd(r.left, r.top, r.right, r.bottom); + clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op); } else { clipped = clipRect->unionWith(r); } break; } - case SkRegion::kXOR_Op: { - ensureClipRegion(); - clipped = clipRegionXor(r.left, r.top, r.right, r.bottom); - break; - } - case SkRegion::kReverseDifference_Op: { - // TODO!!!!!!! - break; - } case SkRegion::kReplace_Op: { setClip(r.left, r.top, r.right, r.bottom); clipped = true; break; } + default: { + ensureClipRegion(); + clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op); + break; + } } if (clipped) { @@ -213,7 +171,7 @@ void Snapshot::setClip(float left, float top, float right, float bottom) { clipRect->set(left, top, right, bottom); #if STENCIL_BUFFER_SIZE if (clipRegion) { - clipRegion->clear(); + clipRegion->setEmpty(); clipRegion = NULL; } #endif diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index 30b03fc..a89b740 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -198,7 +198,7 @@ public: * * This field is used only if STENCIL_BUFFER_SIZE is > 0. */ - Region* clipRegion; + SkRegion* clipRegion; /** * The ancestor layer's dirty region. @@ -223,17 +223,14 @@ private: void ensureClipRegion(); void copyClipRectFromRegion(); - bool clipRegionOr(float left, float top, float right, float bottom); - bool clipRegionXor(float left, float top, float right, float bottom); - bool clipRegionAnd(float left, float top, float right, float bottom); - bool clipRegionNand(float left, float top, float right, float bottom); + bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op); mat4 mTransformRoot; Rect mClipRectRoot; Rect mLocalClip; #if STENCIL_BUFFER_SIZE - Region mClipRegionRoot; + SkRegion mClipRegionRoot; #endif }; // class Snapshot diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp new file mode 100644 index 0000000..9d2c86f --- /dev/null +++ b/libs/hwui/Stencil.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <GLES2/gl2.h> + +#include "Properties.h" +#include "Stencil.h" + +namespace android { +namespace uirenderer { + +Stencil::Stencil(): mState(kDisabled) { +} + +uint32_t Stencil::getStencilSize() { + return STENCIL_BUFFER_SIZE; +} + +void Stencil::clear() { + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); +} + +void Stencil::enableTest() { + if (mState != kTest) { + enable(); + glStencilFunc(GL_LESS, 0x0, 0x1); + // We only want to test, let's keep everything + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + mState = kTest; + } +} + +void Stencil::enableWrite() { + if (mState != kWrite) { + enable(); + glStencilFunc(GL_ALWAYS, 0x1, 0x1); + // The test always passes so the first two values are meaningless + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + mState = kWrite; + } +} + +void Stencil::enable() { + if (!mState == kDisabled) { + glEnable(GL_STENCIL_TEST); + } +} + +void Stencil::disable() { + if (mState != kDisabled) { + glDisable(GL_STENCIL_TEST); + mState = kDisabled; + } +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/Stencil.h b/libs/hwui/Stencil.h new file mode 100644 index 0000000..67ccc78 --- /dev/null +++ b/libs/hwui/Stencil.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_STENCIL_H +#define ANDROID_HWUI_STENCIL_H + +#ifndef LOG_TAG + #define LOG_TAG "OpenGLRenderer" +#endif + +#include <cutils/compiler.h> + +namespace android { +namespace uirenderer { + +/////////////////////////////////////////////////////////////////////////////// +// Stencil buffer management +/////////////////////////////////////////////////////////////////////////////// + +class ANDROID_API Stencil { +public: + Stencil(); + + /** + * Returns the desired size for the stencil buffer. If the returned value + * is 0, then no stencil buffer is required. + */ + ANDROID_API static uint32_t getStencilSize(); + + /** + * Clears the stencil buffer. + */ + void clear(); + + /** + * Enables stencil test. When the stencil test is enabled the stencil + * buffer is not written into. + */ + void enableTest(); + + /** + * Enables stencil write. When stencil write is enabled, the stencil + * test always succeeds and the value 0x1 is written in the stencil + * buffer for each fragment. + */ + void enableWrite(); + + /** + * Disables stencil test and write. + */ + void disable(); + + /** + * Indicates whether either test or write is enabled. + */ + bool isEnabled() { + return mState != kDisabled; + } + +private: + void enable(); + + enum StencilState { + kDisabled, + kTest, + kWrite + }; + + StencilState mState; + +}; // class Stencil + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_STENCIL_H |
