Early kickoff of shadow tasks
bug:26562703
Change-Id: I7cdf18f2c662380bd31c7ffeefd5c3f569e5c1c6
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 0835c29..461e819 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -160,45 +160,6 @@
// Shadow tessellation task processing
///////////////////////////////////////////////////////////////////////////////
-class ShadowTask : public Task<TessellationCache::vertexBuffer_pair_t*> {
-public:
- ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
- const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
- const Vector3& lightCenter, float lightRadius)
- : drawTransform(*drawTransform)
- , localClip(localClip)
- , opaque(opaque)
- , casterPerimeter(*casterPerimeter)
- , transformXY(*transformXY)
- , transformZ(*transformZ)
- , lightCenter(lightCenter)
- , lightRadius(lightRadius) {
- }
-
- ~ShadowTask() {
- TessellationCache::vertexBuffer_pair_t* bufferPair = getResult();
- delete bufferPair->getFirst();
- delete bufferPair->getSecond();
- delete bufferPair;
- }
-
- /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
- * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
- * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
- *
- * These deep copies could be avoided, long term, by cancelling or flushing outstanding tasks
- * before tearning down single-frame LinearAllocators.
- */
- const Matrix4 drawTransform;
- const Rect localClip;
- bool opaque;
- const SkPath casterPerimeter;
- const Matrix4 transformXY;
- const Matrix4 transformZ;
- const Vector3 lightCenter;
- const float lightRadius;
-};
-
static void mapPointFakeZ(Vector3& point, const mat4* transformXY, const mat4* transformZ) {
// map z coordinate with true 3d matrix
point.z = transformZ->mapZ(point);
@@ -288,7 +249,7 @@
~ShadowProcessor() {}
virtual void onProcess(const sp<Task<TessellationCache::vertexBuffer_pair_t*> >& task) override {
- ShadowTask* t = static_cast<ShadowTask*>(task.get());
+ TessellationCache::ShadowTask* t = static_cast<TessellationCache::ShadowTask*>(task.get());
ATRACE_NAME("shadow tessellation");
VertexBuffer* ambientBuffer = new VertexBuffer;
@@ -415,6 +376,29 @@
outBuffers = *(task->getResult());
}
+sp<TessellationCache::ShadowTask> TessellationCache::getShadowTask(
+ const Matrix4* drawTransform, const Rect& localClip,
+ bool opaque, const SkPath* casterPerimeter,
+ const Matrix4* transformXY, const Matrix4* transformZ,
+ const Vector3& lightCenter, float lightRadius) {
+ ShadowDescription key(casterPerimeter, drawTransform);
+ ShadowTask* task = static_cast<ShadowTask*>(mShadowCache.get(key));
+ if (!task) {
+ precacheShadows(drawTransform, localClip, opaque, casterPerimeter,
+ transformXY, transformZ, lightCenter, lightRadius);
+ task = static_cast<ShadowTask*>(mShadowCache.get(key));
+ }
+ LOG_ALWAYS_FATAL_IF(task == nullptr, "shadow not precached");
+ return task;
+}
+
+TessellationCache::ShadowTask::~ShadowTask() {
+ TessellationCache::vertexBuffer_pair_t* bufferPair = getResult();
+ delete bufferPair->getFirst();
+ delete bufferPair->getSecond();
+ delete bufferPair;
+}
+
///////////////////////////////////////////////////////////////////////////////
// Tessellation precaching
///////////////////////////////////////////////////////////////////////////////