summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/Caches.cpp27
-rw-r--r--libs/hwui/Caches.h5
-rw-r--r--libs/hwui/LayerRenderer.cpp7
-rw-r--r--libs/hwui/OpenGLRenderer.cpp16
-rw-r--r--libs/hwui/Rect.h4
5 files changed, 45 insertions, 14 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f210820..214cc92 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -74,6 +74,7 @@ void Caches::init() {
mTexCoordsArrayEnabled = false;
+ scissorEnabled = false;
mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
glActiveTexture(gTextureUnits[0]);
@@ -352,7 +353,9 @@ void Caches::activeTexture(GLuint textureUnit) {
}
void Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
- if (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight) {
+ if (scissorEnabled && (x != mScissorX || y != mScissorY ||
+ width != mScissorWidth || height != mScissorHeight)) {
+
glScissor(x, y, width, height);
mScissorX = x;
@@ -362,6 +365,28 @@ void Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
}
}
+void Caches::enableScissor() {
+ if (!scissorEnabled) {
+ glEnable(GL_SCISSOR_TEST);
+ scissorEnabled = true;
+ }
+}
+
+void Caches::disableScissor() {
+ if (scissorEnabled) {
+ glDisable(GL_SCISSOR_TEST);
+ scissorEnabled = false;
+ }
+}
+
+void Caches::setScissorEnabled(bool enabled) {
+ if (scissorEnabled != enabled) {
+ if (enabled) glEnable(GL_SCISSOR_TEST);
+ else glDisable(GL_SCISSOR_TEST);
+ scissorEnabled = enabled;
+ }
+}
+
void Caches::resetScissor() {
mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
}
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 58361c9..f83e291 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -204,6 +204,10 @@ public:
*/
void resetScissor();
+ void enableScissor();
+ void disableScissor();
+ void setScissorEnabled(bool enabled);
+
/**
* Returns the mesh used to draw regions. Calling this method will
* bind a VBO of type GL_ELEMENT_ARRAY_BUFFER that contains the
@@ -221,6 +225,7 @@ public:
GLenum lastSrcMode;
GLenum lastDstMode;
Program* currentProgram;
+ bool scissorEnabled;
// VBO to draw with
GLuint meshBuffer;
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 65f8c7c..41a5f0d 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -233,9 +233,8 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
layer->getTexture(), 0);
- glDisable(GL_SCISSOR_TEST);
+ caches.disableScissor();
glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_SCISSOR_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
@@ -431,7 +430,7 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f,
bitmap->width(), bitmap->height(), !layer->isBlend());
- glDisable(GL_SCISSOR_TEST);
+ caches.disableScissor();
renderer.translate(0.0f, bitmap->height());
renderer.scale(1.0f, -1.0f);
@@ -460,8 +459,6 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
}
error:
- glEnable(GL_SCISSOR_TEST);
-
#if DEBUG_OPENGL
if (error != GL_NO_ERROR) {
ALOGD("GL error while copying layer into bitmap = 0x%x", error);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 933d012..cbf7b02 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -157,7 +157,6 @@ void OpenGLRenderer::setViewport(int width, int height) {
mFirstSnapshot->viewport.set(0, 0, width, height);
glDisable(GL_DITHER);
- glEnable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnableVertexAttribArray(Program::kBindingPosition);
@@ -181,6 +180,7 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
syncState();
if (!opaque) {
+ mCaches.enableScissor();
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
glClear(GL_COLOR_BUFFER_BIT);
return DrawGlInfo::kStatusDrew;
@@ -250,7 +250,7 @@ void OpenGLRenderer::resume() {
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glEnable(GL_SCISSOR_TEST);
+ mCaches.enableScissor();
mCaches.resetScissor();
dirtyClip();
@@ -651,6 +651,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> sna
#endif
// Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
+ mCaches.enableScissor();
mCaches.setScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f,
clip.getWidth() + 2.0f, clip.getHeight() + 2.0f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -981,7 +982,7 @@ void OpenGLRenderer::clearLayerRegions() {
// The list contains bounds that have already been clipped
// against their initial clip rect, and the current clip
// is likely different so we need to disable clipping here
- glDisable(GL_SCISSOR_TEST);
+ mCaches.disableScissor();
Vertex mesh[count * 6];
Vertex* vertex = mesh;
@@ -1008,8 +1009,6 @@ void OpenGLRenderer::clearLayerRegions() {
setupDrawVertices(&mesh[0].position[0]);
glDrawArrays(GL_TRIANGLES, 0, count * 6);
-
- glEnable(GL_SCISSOR_TEST);
} else {
for (uint32_t i = 0; i < count; i++) {
delete mLayers.itemAt(i);
@@ -1088,7 +1087,12 @@ bool OpenGLRenderer::quickReject(float left, float top, float right, float botto
Rect clipRect(*mSnapshot->clipRect);
clipRect.snapToPixelBoundaries();
- return !clipRect.intersects(r);
+ bool rejected = !clipRect.intersects(r);
+ if (!isDeferred() && !rejected) {
+ mCaches.setScissorEnabled(!clipRect.contains(r));
+ }
+
+ return rejected;
}
bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 2ca4f50..80f39ff 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -125,11 +125,11 @@ public:
return intersect(r.left, r.top, r.right, r.bottom);
}
- bool contains(float l, float t, float r, float b) {
+ inline bool contains(float l, float t, float r, float b) {
return l >= left && t >= top && r <= right && b <= bottom;
}
- bool contains(const Rect& r) {
+ inline bool contains(const Rect& r) {
return contains(r.left, r.top, r.right, r.bottom);
}