From 15fdab5651b8725c47c92196c29c4ba5d8a826fc Mon Sep 17 00:00:00 2001 From: Angel Aguayo Date: Wed, 11 Jan 2023 22:24:35 +0000 Subject: [PATCH] Optimize drawMesh APIs by utilizing a cached GPU based mesh Utilize a GPU based mesh that is cached during the lifecycle a draw list is active. Bug: b/265044322 Test: atest CtsUiRenderingTestCases:MeshTest Change-Id: I6baa2ed027324018c31fd40d10a8f91814a4b469 --- libs/hwui/RecordingCanvas.cpp | 38 ++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index e1030b0faf8ef..ce1e898ec9633 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -45,6 +45,7 @@ #include "SkVertices.h" #include "VectorDrawable.h" #include "include/gpu/GpuTypes.h" // from Skia +#include "include/gpu/GrDirectContext.h" #include "pipeline/skia/AnimatedDrawables.h" #include "pipeline/skia/FunctorDrawable.h" @@ -458,12 +459,43 @@ struct DrawVertices final : Op { struct DrawMesh final : Op { static const auto kType = Type::DrawMesh; DrawMesh(const SkMesh& mesh, sk_sp blender, const SkPaint& paint) - : mesh(mesh), blender(std::move(blender)), paint(paint) {} + : cpuMesh(mesh), blender(std::move(blender)), paint(paint) { + isGpuBased = false; + } - SkMesh mesh; + SkMesh cpuMesh; + mutable SkMesh gpuMesh; sk_sp blender; SkPaint paint; - void draw(SkCanvas* c, const SkMatrix&) const { c->drawMesh(mesh, blender, paint); } + mutable bool isGpuBased; + mutable GrDirectContext::DirectContextID contextId; + void draw(SkCanvas* c, const SkMatrix&) const { + GrDirectContext* directContext = c->recordingContext()->asDirectContext(); + GrDirectContext::DirectContextID id = directContext->directContextID(); + if (!isGpuBased || contextId != id) { + sk_sp vb = + SkMesh::CopyVertexBuffer(directContext, cpuMesh.refVertexBuffer()); + if (!cpuMesh.indexBuffer()) { + gpuMesh = SkMesh::Make(cpuMesh.refSpec(), cpuMesh.mode(), vb, cpuMesh.vertexCount(), + cpuMesh.vertexOffset(), cpuMesh.refUniforms(), + cpuMesh.bounds()) + .mesh; + } else { + sk_sp ib = + SkMesh::CopyIndexBuffer(directContext, cpuMesh.refIndexBuffer()); + gpuMesh = SkMesh::MakeIndexed(cpuMesh.refSpec(), cpuMesh.mode(), vb, + cpuMesh.vertexCount(), cpuMesh.vertexOffset(), ib, + cpuMesh.indexCount(), cpuMesh.indexOffset(), + cpuMesh.refUniforms(), cpuMesh.bounds()) + .mesh; + } + + isGpuBased = true; + contextId = id; + } + + c->drawMesh(gpuMesh, blender, paint); + } }; struct DrawAtlas final : Op { static const auto kType = Type::DrawAtlas;