summaryrefslogtreecommitdiff
path: root/libs/hwui/OpenGLRenderer.cpp
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2011-01-16 12:54:25 -0800
committer Romain Guy <romainguy@google.com> 2011-01-16 12:54:25 -0800
commitf219da5e32e85deb442468ee9a63bb28eb198557 (patch)
tree3d27f5c3a1fcce028ca12aa7dc7331f95d8ae8c0 /libs/hwui/OpenGLRenderer.cpp
parenta47aa87a19c733e28d9d2db1c4eb7f29d668db7b (diff)
Don't blend transparent pixels when rendering layers.
With this change, the rendere keeps track of what regions are rendered into and generates a mesh that matches these regions exactly. The mesh is used to composite the layer on screen. Change-Id: I1f342576b9134fb29caff7fb8f4c1da179fe956d
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp55
1 files changed, 40 insertions, 15 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b9332327df99..16a1de7adc32 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -615,6 +615,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
const float alpha = layer->alpha / 255.0f;
const float texX = 1.0f / float(layer->width);
const float texY = 1.0f / float(layer->height);
+ const float height = rect.getHeight();
TextureVertex* mesh = mCaches.getRegionMesh();
GLsizei numQuads = 0;
@@ -636,9 +637,9 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
const android::Rect* r = &rects[i];
const float u1 = r->left * texX;
- const float v1 = (rect.getHeight() - r->top) * texY;
+ const float v1 = (height - r->top) * texY;
const float u2 = r->right * texX;
- const float v2 = (rect.getHeight() - r->bottom) * texY;
+ const float v2 = (height - r->bottom) * texY;
// TODO: Reject quads outside of the clip
TextureVertex::set(mesh++, r->left, r->top, u1, v1);
@@ -694,10 +695,10 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
void OpenGLRenderer::dirtyLayer(const float left, const float top,
const float right, const float bottom, const mat4 transform) {
#if RENDER_LAYERS_AS_REGIONS
- if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ if (hasLayer()) {
Rect bounds(left, top, right, bottom);
transform.mapRect(bounds);
- dirtyLayerUnchecked(bounds, mSnapshot->region);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -705,9 +706,9 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top,
void OpenGLRenderer::dirtyLayer(const float left, const float top,
const float right, const float bottom) {
#if RENDER_LAYERS_AS_REGIONS
- if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ if (hasLayer()) {
Rect bounds(left, top, right, bottom);
- dirtyLayerUnchecked(bounds, mSnapshot->region);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -1419,24 +1420,20 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
#if RENDER_LAYERS_AS_REGIONS
- bool hasLayer = (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
+ bool hasActiveLayer = hasLayer();
#else
- bool hasLayer = false;
+ bool hasActiveLayer = false;
#endif
mCaches.unbindMeshBuffer();
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
- hasLayer ? &bounds : NULL)) {
+ hasActiveLayer ? &bounds : NULL)) {
#if RENDER_LAYERS_AS_REGIONS
- if (hasLayer) {
+ if (hasActiveLayer) {
if (!pureTranslate) {
mSnapshot->transform->mapRect(bounds);
}
- bounds.intersect(*mSnapshot->clipRect);
- bounds.snapToPixelBoundaries();
-
- android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
- mSnapshot->region->orSelf(dirty);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -1501,8 +1498,36 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
layer->alpha = alpha;
layer->mode = mode;
+
+#if RENDER_LAYERS_AS_REGIONS
+ if (layer->region.isRect()) {
+ const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
+ composeLayerRect(layer, r);
+ } else if (!layer->region.isEmpty() && layer->mesh) {
+ const Rect& rect = layer->layer;
+
+ setupDraw();
+ setupDrawWithTexture();
+ setupDrawColor(alpha, alpha, alpha, alpha);
+ setupDrawColorFilter();
+ setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
+ setupDrawProgram();
+ setupDrawDirtyRegionsDisabled();
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawTexture(layer->texture);
+ setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+ setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
+
+ glDrawElements(GL_TRIANGLES, layer->meshElementCount,
+ GL_UNSIGNED_SHORT, layer->meshIndices);
+
+ finishDrawTexture();
+ }
+#else
const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
composeLayerRect(layer, r);
+#endif
}
///////////////////////////////////////////////////////////////////////////////