summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorztenghui <ztenghui@google.com>2014-03-20 22:30:58 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-03-20 22:30:59 +0000
commit32ff540c74623d92a8bf1e0a0ae3153a7a6d13e4 (patch)
treef4fae2487054de585d465a9a77f3f38539d64c8b /libs/hwui
parent63f4e55ba5df622a47ea9d60ef0626995f3d677a (diff)
parentaf6f7ed8dd4288a41d0a07a1f0f0be7d6d035b33 (diff)
downloadframeworks_base-32ff540c74623d92a8bf1e0a0ae3153a7a6d13e4.zip
frameworks_base-32ff540c74623d92a8bf1e0a0ae3153a7a6d13e4.tar.gz
frameworks_base-32ff540c74623d92a8bf1e0a0ae3153a7a6d13e4.tar.bz2
Merge "Early rejection on shadows which are outside of the clip bound."
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp16
-rw-r--r--libs/hwui/Rect.h8
-rw-r--r--libs/hwui/ShadowTessellator.cpp28
-rw-r--r--libs/hwui/ShadowTessellator.h6
4 files changed, 52 insertions, 6 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cb8155b..cdd789d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -3226,11 +3226,13 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
const int casterVertexCount = casterVertices2d.size();
Vector3 casterPolygon[casterVertexCount];
float minZ = FLT_MAX;
+ float maxZ = -FLT_MAX;
for (int i = 0; i < casterVertexCount; i++) {
const Vertex& point2d = casterVertices2d[i];
casterPolygon[i] = Vector3(point2d.x, point2d.y, 0);
mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
minZ = fmin(minZ, casterPolygon[i].z);
+ maxZ = fmax(maxZ, casterPolygon[i].z);
}
// map the centroid of the caster into 3d
@@ -3248,6 +3250,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
}
centroid3d.z += casterLift;
}
+
+ // Check whether we want to draw the shadow at all by checking the caster's
+ // bounds against clip.
+ // We only have ortho projection, so we can just ignore the Z in caster for
+ // simple rejection calculation.
+ Rect localClip = mSnapshot->getLocalClip();
+ Rect casterBounds(casterOutline->getBounds());
+ casterTransformXY.mapRect(casterBounds);
+
bool isCasterOpaque = (casterAlpha == 1.0f);
// draw caster's shadows
if (mCaches.propertyAmbientShadowStrength > 0) {
@@ -3255,7 +3266,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
VertexBuffer ambientShadowVertexBuffer;
VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow(
isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
- ambientShadowVertexBuffer);
+ casterBounds, localClip, maxZ, ambientShadowVertexBuffer);
drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint);
}
@@ -3266,7 +3277,8 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c
mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow(
isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale,
- *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer);
+ *currentTransform(), getWidth(), getHeight(), casterBounds, localClip,
+ spotShadowVertexBuffer);
drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint);
}
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index c230149..0083b77 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -18,6 +18,7 @@
#define ANDROID_HWUI_RECT_H
#include <cmath>
+#include <SkRect.h>
#include <utils/Log.h>
@@ -68,6 +69,13 @@ public:
bottom(height) {
}
+ inline Rect(const SkRect& rect):
+ left(rect.fLeft),
+ top(rect.fTop),
+ right(rect.fRight),
+ bottom(rect.fBottom) {
+ }
+
friend int operator==(const Rect& a, const Rect& b) {
return !memcmp(&a, &b, sizeof(a));
}
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 771904a..4d0edfb 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -35,7 +35,8 @@ static inline T max(T a, T b) {
VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
const Vector3* casterPolygon, int casterVertexCount,
- const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) {
+ const Vector3& centroid3d, const Rect& casterBounds,
+ const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer) {
ATRACE_CALL();
// A bunch of parameters to tweak the shadow.
@@ -43,6 +44,16 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
const float heightFactor = 1.0f / 128;
const float geomFactor = 64;
+ Rect ambientShadowBounds(casterBounds);
+ ambientShadowBounds.outset(maxZ * geomFactor * heightFactor);
+
+ if (!localClip.intersects(ambientShadowBounds)) {
+#if DEBUG_SHADOW
+ ALOGD("Ambient shadow is out of clip rect!");
+#endif
+ return kVertexBufferMode_OnePolyRingShadow;
+ }
+
return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon,
casterVertexCount, centroid3d, heightFactor, geomFactor,
shadowVertexBuffer);
@@ -52,7 +63,8 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
const Vector3* casterPolygon, int casterVertexCount,
const Vector3& lightPosScale, const mat4& receiverTransform,
- int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
+ int screenWidth, int screenHeight, const Rect& casterBounds,
+ const Rect& localClip, VertexBuffer& shadowVertexBuffer) {
ATRACE_CALL();
// A bunch of parameters to tweak the shadow.
@@ -73,6 +85,18 @@ VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
const float lightSize = maximal / 4;
const int lightVertexCount = 8;
+ // Now light and caster are both in local space, we will check whether
+ // the shadow is within the clip area.
+ Rect lightRect = Rect(lightCenter.x - lightSize, lightCenter.y - lightSize,
+ lightCenter.x + lightSize, lightCenter.y + lightSize);
+ lightRect.unionWith(localClip);
+ if (!lightRect.intersects(casterBounds)) {
+#if DEBUG_SHADOW
+ ALOGD("Spot shadow is out of clip rect!");
+#endif
+ return kVertexBufferMode_OnePolyRingShadow;
+ }
+
VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque,
casterPolygon, casterVertexCount, lightCenter, lightSize,
lightVertexCount, shadowVertexBuffer);
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index ab039fa..ff3de74 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -66,12 +66,14 @@ class ShadowTessellator {
public:
static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque,
const Vector3* casterPolygon, int casterVertexCount,
- const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer);
+ const Vector3& centroid3d, const Rect& casterBounds,
+ const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer);
static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque,
const Vector3* casterPolygon, int casterVertexCount,
const Vector3& lightPosScale, const mat4& receiverTransform,
- int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer);
+ int screenWidth, int screenHeight, const Rect& casterBounds,
+ const Rect& localClip, VertexBuffer& shadowVertexBuffer);
static void generateShadowIndices(uint16_t* shadowIndices);