summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-08-31 17:14:30 -0700
committerRomain Guy <romainguy@google.com>2012-08-31 17:17:40 -0700
commitdfe082f63e94cde9aee271c94d13de5e7217e036 (patch)
tree938584a2a121427d00521a10fe95ce0e34588a06 /libs
parentfbb4321b94927fd6bd39d327fe56787989b11c71 (diff)
downloadframeworks_base-dfe082f63e94cde9aee271c94d13de5e7217e036.zip
frameworks_base-dfe082f63e94cde9aee271c94d13de5e7217e036.tar.gz
frameworks_base-dfe082f63e94cde9aee271c94d13de5e7217e036.tar.bz2
Add more support for transformed clip rects and paths
Change-Id: I41791b1e1bffef77d503dc9e52428395d2309688
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Caches.h7
-rw-r--r--libs/hwui/GradientCache.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.h6
-rw-r--r--libs/hwui/Snapshot.cpp76
-rw-r--r--libs/hwui/Snapshot.h9
-rw-r--r--libs/hwui/Stencil.cpp71
-rw-r--r--libs/hwui/Stencil.h89
9 files changed, 188 insertions, 77 deletions
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/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 2e4e349..b50ed10 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -57,7 +57,7 @@ GradientCache::GradientCache():
INIT_LOGD(" Using default gradient cache size of %.2fMB", DEFAULT_GRADIENT_CACHE_SIZE);
}
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ mMaxTextureSize = Caches::getInstance().maxTextureSize;
mCache.setOnEntryRemovedListener(this);
}
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