Merge "Add more support for transformed clip rects and paths" into jb-mr1-dev
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -28,6 +28,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
|
||||
SkiaColorFilter.cpp \
|
||||
SkiaShader.cpp \
|
||||
Snapshot.cpp \
|
||||
Stencil.cpp \
|
||||
TextureCache.cpp \
|
||||
TextDropShadowCache.cpp
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -139,10 +139,6 @@ void OpenGLRenderer::endMark() const {
|
||||
// Setup
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t OpenGLRenderer::getStencilSize() {
|
||||
return STENCIL_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::isDeferred() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -207,12 +207,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
71
libs/hwui/Stencil.cpp
Normal file
71
libs/hwui/Stencil.cpp
Normal file
@@ -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
|
||||
89
libs/hwui/Stencil.h
Normal file
89
libs/hwui/Stencil.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user