Fix Mesh UAF, uniform handling, and performance bug.
Prior to this change, the render thread would only receive a non-owning
pointer or reference to a Mesh. Also because the Mesh itself was passed
by pointer, the refcount in its uniform sk_sp<SkData> would not be
incremented until an SkMesh was updated on the render thread, causing
uniform setting calls on the UI thread to impact prior draw calls with
the same mesh. The dirty flag used for the uniforms was also signaling a
reupload of vertex and index data to the GPU.
This fix adds a MeshBufferData class to handle keeping Skia buffers
up-to-date, and a Mesh::Snapshot class that carries shared ownership of
all pieces needed to construct an SkMesh. The snapshot is stored on the
render thread by value and increments the refcount of the uniform
sk_sp<SkData>.
Because the current Android Mesh API does not support partial buffer
updates, there is no need for a dirty flag, as comparing the
DirectContextID and checking if the buffers have been created is
sufficient. Creating an SkMesh is performed lazily inside the SkMesh
getter of the snapshot.
BUG: 328507000
Test: atest CtsUiRenderingTestCases:MeshTest
Change-Id: Iabe83dca462d4526c118047621b131009032d35b
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 0b739c3..72e83af 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -596,8 +596,8 @@
if (recordingContext) {
context = recordingContext->asDirectContext();
}
- mesh.updateSkMesh(context);
- mCanvas->drawMesh(mesh.getSkMesh(), blender, paint);
+ mesh.refBufferData()->updateBuffers(context);
+ mCanvas->drawMesh(mesh.takeSnapshot().getSkMesh(), blender, paint);
}
// ----------------------------------------------------------------------------