1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #ifndef MESH_H_ 18*d57664e9SAndroid Build Coastguard Worker #define MESH_H_ 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker #include <SkMesh.h> 21*d57664e9SAndroid Build Coastguard Worker #include <include/gpu/ganesh/GrDirectContext.h> 22*d57664e9SAndroid Build Coastguard Worker #include <include/gpu/ganesh/SkMeshGanesh.h> 23*d57664e9SAndroid Build Coastguard Worker #include <jni.h> 24*d57664e9SAndroid Build Coastguard Worker #include <log/log.h> 25*d57664e9SAndroid Build Coastguard Worker 26*d57664e9SAndroid Build Coastguard Worker #include <utility> 27*d57664e9SAndroid Build Coastguard Worker 28*d57664e9SAndroid Build Coastguard Worker namespace android { 29*d57664e9SAndroid Build Coastguard Worker 30*d57664e9SAndroid Build Coastguard Worker class MeshUniformBuilder { 31*d57664e9SAndroid Build Coastguard Worker public: 32*d57664e9SAndroid Build Coastguard Worker struct MeshUniform { 33*d57664e9SAndroid Build Coastguard Worker template <typename T> 34*d57664e9SAndroid Build Coastguard Worker std::enable_if_t<std::is_trivially_copyable<T>::value, MeshUniform> operator=( 35*d57664e9SAndroid Build Coastguard Worker const T& val) { 36*d57664e9SAndroid Build Coastguard Worker if (!fVar) { 37*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Assigning to missing variable"); 38*d57664e9SAndroid Build Coastguard Worker } else if (sizeof(val) != fVar->sizeInBytes()) { 39*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Incorrect value size"); 40*d57664e9SAndroid Build Coastguard Worker } else { 41*d57664e9SAndroid Build Coastguard Worker void* dst = reinterpret_cast<void*>( 42*d57664e9SAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(fOwner->writableUniformData()) + fVar->offset); 43*d57664e9SAndroid Build Coastguard Worker memcpy(dst, &val, sizeof(val)); 44*d57664e9SAndroid Build Coastguard Worker } 45*d57664e9SAndroid Build Coastguard Worker } 46*d57664e9SAndroid Build Coastguard Worker 47*d57664e9SAndroid Build Coastguard Worker MeshUniform& operator=(const SkMatrix& val) { 48*d57664e9SAndroid Build Coastguard Worker if (!fVar) { 49*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Assigning to missing variable"); 50*d57664e9SAndroid Build Coastguard Worker } else if (fVar->sizeInBytes() != 9 * sizeof(float)) { 51*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Incorrect value size"); 52*d57664e9SAndroid Build Coastguard Worker } else { 53*d57664e9SAndroid Build Coastguard Worker float* data = reinterpret_cast<float*>( 54*d57664e9SAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(fOwner->writableUniformData()) + fVar->offset); 55*d57664e9SAndroid Build Coastguard Worker data[0] = val.get(0); 56*d57664e9SAndroid Build Coastguard Worker data[1] = val.get(3); 57*d57664e9SAndroid Build Coastguard Worker data[2] = val.get(6); 58*d57664e9SAndroid Build Coastguard Worker data[3] = val.get(1); 59*d57664e9SAndroid Build Coastguard Worker data[4] = val.get(4); 60*d57664e9SAndroid Build Coastguard Worker data[5] = val.get(7); 61*d57664e9SAndroid Build Coastguard Worker data[6] = val.get(2); 62*d57664e9SAndroid Build Coastguard Worker data[7] = val.get(5); 63*d57664e9SAndroid Build Coastguard Worker data[8] = val.get(8); 64*d57664e9SAndroid Build Coastguard Worker } 65*d57664e9SAndroid Build Coastguard Worker return *this; 66*d57664e9SAndroid Build Coastguard Worker } 67*d57664e9SAndroid Build Coastguard Worker 68*d57664e9SAndroid Build Coastguard Worker template <typename T> setMeshUniform69*d57664e9SAndroid Build Coastguard Worker bool set(const T val[], const int count) { 70*d57664e9SAndroid Build Coastguard Worker static_assert(std::is_trivially_copyable<T>::value, "Value must be trivial copyable"); 71*d57664e9SAndroid Build Coastguard Worker if (!fVar) { 72*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Assigning to missing variable"); 73*d57664e9SAndroid Build Coastguard Worker return false; 74*d57664e9SAndroid Build Coastguard Worker } else if (sizeof(T) * count != fVar->sizeInBytes()) { 75*d57664e9SAndroid Build Coastguard Worker LOG_FATAL("Incorrect value size"); 76*d57664e9SAndroid Build Coastguard Worker return false; 77*d57664e9SAndroid Build Coastguard Worker } else { 78*d57664e9SAndroid Build Coastguard Worker void* dst = reinterpret_cast<void*>( 79*d57664e9SAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(fOwner->writableUniformData()) + fVar->offset); 80*d57664e9SAndroid Build Coastguard Worker memcpy(dst, val, sizeof(T) * count); 81*d57664e9SAndroid Build Coastguard Worker } 82*d57664e9SAndroid Build Coastguard Worker return true; 83*d57664e9SAndroid Build Coastguard Worker } 84*d57664e9SAndroid Build Coastguard Worker 85*d57664e9SAndroid Build Coastguard Worker MeshUniformBuilder* fOwner; 86*d57664e9SAndroid Build Coastguard Worker const SkRuntimeEffect::Uniform* fVar; 87*d57664e9SAndroid Build Coastguard Worker }; uniform(std::string_view name)88*d57664e9SAndroid Build Coastguard Worker MeshUniform uniform(std::string_view name) { return {this, fMeshSpec->findUniform(name)}; } 89*d57664e9SAndroid Build Coastguard Worker MeshUniformBuilder(sk_sp<SkMeshSpecification> meshSpec)90*d57664e9SAndroid Build Coastguard Worker explicit MeshUniformBuilder(sk_sp<SkMeshSpecification> meshSpec) { 91*d57664e9SAndroid Build Coastguard Worker fMeshSpec = sk_sp(meshSpec); 92*d57664e9SAndroid Build Coastguard Worker fUniforms = (SkData::MakeZeroInitialized(meshSpec->uniformSize())); 93*d57664e9SAndroid Build Coastguard Worker } 94*d57664e9SAndroid Build Coastguard Worker 95*d57664e9SAndroid Build Coastguard Worker sk_sp<SkData> fUniforms; 96*d57664e9SAndroid Build Coastguard Worker 97*d57664e9SAndroid Build Coastguard Worker private: writableUniformData()98*d57664e9SAndroid Build Coastguard Worker void* writableUniformData() { 99*d57664e9SAndroid Build Coastguard Worker if (!fUniforms->unique()) { 100*d57664e9SAndroid Build Coastguard Worker fUniforms = SkData::MakeWithCopy(fUniforms->data(), fUniforms->size()); 101*d57664e9SAndroid Build Coastguard Worker } 102*d57664e9SAndroid Build Coastguard Worker return fUniforms->writable_data(); 103*d57664e9SAndroid Build Coastguard Worker } 104*d57664e9SAndroid Build Coastguard Worker 105*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMeshSpecification> fMeshSpec; 106*d57664e9SAndroid Build Coastguard Worker }; 107*d57664e9SAndroid Build Coastguard Worker 108*d57664e9SAndroid Build Coastguard Worker // Storage for CPU and GPU copies of the vertex and index data of a mesh. 109*d57664e9SAndroid Build Coastguard Worker class MeshBufferData { 110*d57664e9SAndroid Build Coastguard Worker public: MeshBufferData(std::vector<uint8_t> vertexData,int32_t vertexCount,int32_t vertexOffset,std::vector<uint8_t> indexData,int32_t indexCount,int32_t indexOffset)111*d57664e9SAndroid Build Coastguard Worker MeshBufferData(std::vector<uint8_t> vertexData, int32_t vertexCount, int32_t vertexOffset, 112*d57664e9SAndroid Build Coastguard Worker std::vector<uint8_t> indexData, int32_t indexCount, int32_t indexOffset) 113*d57664e9SAndroid Build Coastguard Worker : mVertexCount(vertexCount) 114*d57664e9SAndroid Build Coastguard Worker , mVertexOffset(vertexOffset) 115*d57664e9SAndroid Build Coastguard Worker , mIndexCount(indexCount) 116*d57664e9SAndroid Build Coastguard Worker , mIndexOffset(indexOffset) 117*d57664e9SAndroid Build Coastguard Worker , mVertexData(std::move(vertexData)) 118*d57664e9SAndroid Build Coastguard Worker , mIndexData(std::move(indexData)) {} 119*d57664e9SAndroid Build Coastguard Worker updateBuffers(GrDirectContext * context)120*d57664e9SAndroid Build Coastguard Worker void updateBuffers(GrDirectContext* context) const { 121*d57664e9SAndroid Build Coastguard Worker GrDirectContext::DirectContextID currentId = context == nullptr 122*d57664e9SAndroid Build Coastguard Worker ? GrDirectContext::DirectContextID() 123*d57664e9SAndroid Build Coastguard Worker : context->directContextID(); 124*d57664e9SAndroid Build Coastguard Worker if (currentId == mSkiaBuffers.fGenerationId && mSkiaBuffers.fVertexBuffer != nullptr) { 125*d57664e9SAndroid Build Coastguard Worker // Nothing to update since the Android API does not support partial updates yet. 126*d57664e9SAndroid Build Coastguard Worker return; 127*d57664e9SAndroid Build Coastguard Worker } 128*d57664e9SAndroid Build Coastguard Worker 129*d57664e9SAndroid Build Coastguard Worker mSkiaBuffers.fVertexBuffer = 130*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ 131*d57664e9SAndroid Build Coastguard Worker SkMeshes::MakeVertexBuffer(context, mVertexData.data(), mVertexData.size()); 132*d57664e9SAndroid Build Coastguard Worker #else 133*d57664e9SAndroid Build Coastguard Worker SkMeshes::MakeVertexBuffer(mVertexData.data(), mVertexData.size()); 134*d57664e9SAndroid Build Coastguard Worker #endif 135*d57664e9SAndroid Build Coastguard Worker if (mIndexCount != 0) { 136*d57664e9SAndroid Build Coastguard Worker mSkiaBuffers.fIndexBuffer = 137*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ 138*d57664e9SAndroid Build Coastguard Worker SkMeshes::MakeIndexBuffer(context, mIndexData.data(), mIndexData.size()); 139*d57664e9SAndroid Build Coastguard Worker #else 140*d57664e9SAndroid Build Coastguard Worker SkMeshes::MakeIndexBuffer(mIndexData.data(), mIndexData.size()); 141*d57664e9SAndroid Build Coastguard Worker #endif 142*d57664e9SAndroid Build Coastguard Worker } 143*d57664e9SAndroid Build Coastguard Worker mSkiaBuffers.fGenerationId = currentId; 144*d57664e9SAndroid Build Coastguard Worker } 145*d57664e9SAndroid Build Coastguard Worker vertexBuffer()146*d57664e9SAndroid Build Coastguard Worker SkMesh::VertexBuffer* vertexBuffer() const { return mSkiaBuffers.fVertexBuffer.get(); } 147*d57664e9SAndroid Build Coastguard Worker refVertexBuffer()148*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMesh::VertexBuffer> refVertexBuffer() const { return mSkiaBuffers.fVertexBuffer; } vertexCount()149*d57664e9SAndroid Build Coastguard Worker int32_t vertexCount() const { return mVertexCount; } vertexOffset()150*d57664e9SAndroid Build Coastguard Worker int32_t vertexOffset() const { return mVertexOffset; } 151*d57664e9SAndroid Build Coastguard Worker refIndexBuffer()152*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMesh::IndexBuffer> refIndexBuffer() const { return mSkiaBuffers.fIndexBuffer; } indexCount()153*d57664e9SAndroid Build Coastguard Worker int32_t indexCount() const { return mIndexCount; } indexOffset()154*d57664e9SAndroid Build Coastguard Worker int32_t indexOffset() const { return mIndexOffset; } 155*d57664e9SAndroid Build Coastguard Worker vertexData()156*d57664e9SAndroid Build Coastguard Worker const std::vector<uint8_t>& vertexData() const { return mVertexData; } indexData()157*d57664e9SAndroid Build Coastguard Worker const std::vector<uint8_t>& indexData() const { return mIndexData; } 158*d57664e9SAndroid Build Coastguard Worker 159*d57664e9SAndroid Build Coastguard Worker private: 160*d57664e9SAndroid Build Coastguard Worker struct CachedSkiaBuffers { 161*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMesh::VertexBuffer> fVertexBuffer; 162*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMesh::IndexBuffer> fIndexBuffer; 163*d57664e9SAndroid Build Coastguard Worker GrDirectContext::DirectContextID fGenerationId = GrDirectContext::DirectContextID(); 164*d57664e9SAndroid Build Coastguard Worker }; 165*d57664e9SAndroid Build Coastguard Worker 166*d57664e9SAndroid Build Coastguard Worker mutable CachedSkiaBuffers mSkiaBuffers; 167*d57664e9SAndroid Build Coastguard Worker int32_t mVertexCount = 0; 168*d57664e9SAndroid Build Coastguard Worker int32_t mVertexOffset = 0; 169*d57664e9SAndroid Build Coastguard Worker int32_t mIndexCount = 0; 170*d57664e9SAndroid Build Coastguard Worker int32_t mIndexOffset = 0; 171*d57664e9SAndroid Build Coastguard Worker std::vector<uint8_t> mVertexData; 172*d57664e9SAndroid Build Coastguard Worker std::vector<uint8_t> mIndexData; 173*d57664e9SAndroid Build Coastguard Worker }; 174*d57664e9SAndroid Build Coastguard Worker 175*d57664e9SAndroid Build Coastguard Worker class Mesh { 176*d57664e9SAndroid Build Coastguard Worker public: 177*d57664e9SAndroid Build Coastguard Worker // A snapshot of the mesh for use by the render thread. 178*d57664e9SAndroid Build Coastguard Worker // 179*d57664e9SAndroid Build Coastguard Worker // After a snapshot is taken, future uniform changes to the original Mesh will not modify the 180*d57664e9SAndroid Build Coastguard Worker // uniforms returned by makeSkMesh. 181*d57664e9SAndroid Build Coastguard Worker class Snapshot { 182*d57664e9SAndroid Build Coastguard Worker public: 183*d57664e9SAndroid Build Coastguard Worker Snapshot() = delete; 184*d57664e9SAndroid Build Coastguard Worker Snapshot(const Snapshot&) = default; 185*d57664e9SAndroid Build Coastguard Worker Snapshot(Snapshot&&) = default; 186*d57664e9SAndroid Build Coastguard Worker Snapshot& operator=(const Snapshot&) = default; 187*d57664e9SAndroid Build Coastguard Worker Snapshot& operator=(Snapshot&&) = default; 188*d57664e9SAndroid Build Coastguard Worker ~Snapshot() = default; 189*d57664e9SAndroid Build Coastguard Worker getSkMesh()190*d57664e9SAndroid Build Coastguard Worker const SkMesh& getSkMesh() const { 191*d57664e9SAndroid Build Coastguard Worker SkMesh::VertexBuffer* vertexBuffer = mBufferData->vertexBuffer(); 192*d57664e9SAndroid Build Coastguard Worker LOG_FATAL_IF(vertexBuffer == nullptr, 193*d57664e9SAndroid Build Coastguard Worker "Attempt to obtain SkMesh when vertexBuffer has not been created, did you " 194*d57664e9SAndroid Build Coastguard Worker "forget to call MeshBufferData::updateBuffers with a GrDirectContext?"); 195*d57664e9SAndroid Build Coastguard Worker if (vertexBuffer != mMesh.vertexBuffer()) mMesh = makeSkMesh(); 196*d57664e9SAndroid Build Coastguard Worker return mMesh; 197*d57664e9SAndroid Build Coastguard Worker } 198*d57664e9SAndroid Build Coastguard Worker 199*d57664e9SAndroid Build Coastguard Worker private: 200*d57664e9SAndroid Build Coastguard Worker friend class Mesh; 201*d57664e9SAndroid Build Coastguard Worker Snapshot(sk_sp<SkMeshSpecification> meshSpec,SkMesh::Mode mode,std::shared_ptr<const MeshBufferData> bufferData,sk_sp<const SkData> uniforms,const SkRect & bounds)202*d57664e9SAndroid Build Coastguard Worker Snapshot(sk_sp<SkMeshSpecification> meshSpec, SkMesh::Mode mode, 203*d57664e9SAndroid Build Coastguard Worker std::shared_ptr<const MeshBufferData> bufferData, sk_sp<const SkData> uniforms, 204*d57664e9SAndroid Build Coastguard Worker const SkRect& bounds) 205*d57664e9SAndroid Build Coastguard Worker : mMeshSpec(std::move(meshSpec)) 206*d57664e9SAndroid Build Coastguard Worker , mMode(mode) 207*d57664e9SAndroid Build Coastguard Worker , mBufferData(std::move(bufferData)) 208*d57664e9SAndroid Build Coastguard Worker , mUniforms(std::move(uniforms)) 209*d57664e9SAndroid Build Coastguard Worker , mBounds(bounds) {} 210*d57664e9SAndroid Build Coastguard Worker makeSkMesh()211*d57664e9SAndroid Build Coastguard Worker SkMesh makeSkMesh() const { 212*d57664e9SAndroid Build Coastguard Worker const MeshBufferData& d = *mBufferData; 213*d57664e9SAndroid Build Coastguard Worker if (d.indexCount() != 0) { 214*d57664e9SAndroid Build Coastguard Worker return SkMesh::MakeIndexed(mMeshSpec, mMode, d.refVertexBuffer(), d.vertexCount(), 215*d57664e9SAndroid Build Coastguard Worker d.vertexOffset(), d.refIndexBuffer(), d.indexCount(), 216*d57664e9SAndroid Build Coastguard Worker d.indexOffset(), mUniforms, 217*d57664e9SAndroid Build Coastguard Worker SkSpan<SkRuntimeEffect::ChildPtr>(), mBounds) 218*d57664e9SAndroid Build Coastguard Worker .mesh; 219*d57664e9SAndroid Build Coastguard Worker } 220*d57664e9SAndroid Build Coastguard Worker return SkMesh::Make(mMeshSpec, mMode, d.refVertexBuffer(), d.vertexCount(), 221*d57664e9SAndroid Build Coastguard Worker d.vertexOffset(), mUniforms, SkSpan<SkRuntimeEffect::ChildPtr>(), 222*d57664e9SAndroid Build Coastguard Worker mBounds) 223*d57664e9SAndroid Build Coastguard Worker .mesh; 224*d57664e9SAndroid Build Coastguard Worker } 225*d57664e9SAndroid Build Coastguard Worker 226*d57664e9SAndroid Build Coastguard Worker mutable SkMesh mMesh; 227*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMeshSpecification> mMeshSpec; 228*d57664e9SAndroid Build Coastguard Worker SkMesh::Mode mMode; 229*d57664e9SAndroid Build Coastguard Worker std::shared_ptr<const MeshBufferData> mBufferData; 230*d57664e9SAndroid Build Coastguard Worker sk_sp<const SkData> mUniforms; 231*d57664e9SAndroid Build Coastguard Worker SkRect mBounds; 232*d57664e9SAndroid Build Coastguard Worker }; 233*d57664e9SAndroid Build Coastguard Worker Mesh(sk_sp<SkMeshSpecification> meshSpec,SkMesh::Mode mode,std::vector<uint8_t> vertexData,int32_t vertexCount,int32_t vertexOffset,const SkRect & bounds)234*d57664e9SAndroid Build Coastguard Worker Mesh(sk_sp<SkMeshSpecification> meshSpec, SkMesh::Mode mode, std::vector<uint8_t> vertexData, 235*d57664e9SAndroid Build Coastguard Worker int32_t vertexCount, int32_t vertexOffset, const SkRect& bounds) 236*d57664e9SAndroid Build Coastguard Worker : Mesh(std::move(meshSpec), mode, std::move(vertexData), vertexCount, vertexOffset, 237*d57664e9SAndroid Build Coastguard Worker /* indexData = */ {}, /* indexCount = */ 0, /* indexOffset = */ 0, bounds) {} 238*d57664e9SAndroid Build Coastguard Worker Mesh(sk_sp<SkMeshSpecification> meshSpec,SkMesh::Mode mode,std::vector<uint8_t> vertexData,int32_t vertexCount,int32_t vertexOffset,std::vector<uint8_t> indexData,int32_t indexCount,int32_t indexOffset,const SkRect & bounds)239*d57664e9SAndroid Build Coastguard Worker Mesh(sk_sp<SkMeshSpecification> meshSpec, SkMesh::Mode mode, std::vector<uint8_t> vertexData, 240*d57664e9SAndroid Build Coastguard Worker int32_t vertexCount, int32_t vertexOffset, std::vector<uint8_t> indexData, 241*d57664e9SAndroid Build Coastguard Worker int32_t indexCount, int32_t indexOffset, const SkRect& bounds) 242*d57664e9SAndroid Build Coastguard Worker : mMeshSpec(std::move(meshSpec)) 243*d57664e9SAndroid Build Coastguard Worker , mMode(mode) 244*d57664e9SAndroid Build Coastguard Worker , mBufferData(std::make_shared<MeshBufferData>(std::move(vertexData), vertexCount, 245*d57664e9SAndroid Build Coastguard Worker vertexOffset, std::move(indexData), 246*d57664e9SAndroid Build Coastguard Worker indexCount, indexOffset)) 247*d57664e9SAndroid Build Coastguard Worker , mUniformBuilder(mMeshSpec) 248*d57664e9SAndroid Build Coastguard Worker , mBounds(bounds) {} 249*d57664e9SAndroid Build Coastguard Worker 250*d57664e9SAndroid Build Coastguard Worker Mesh(Mesh&&) = default; 251*d57664e9SAndroid Build Coastguard Worker 252*d57664e9SAndroid Build Coastguard Worker Mesh& operator=(Mesh&&) = default; 253*d57664e9SAndroid Build Coastguard Worker 254*d57664e9SAndroid Build Coastguard Worker [[nodiscard]] std::tuple<bool, SkString> validate(); 255*d57664e9SAndroid Build Coastguard Worker refBufferData()256*d57664e9SAndroid Build Coastguard Worker std::shared_ptr<const MeshBufferData> refBufferData() const { return mBufferData; } 257*d57664e9SAndroid Build Coastguard Worker takeSnapshot()258*d57664e9SAndroid Build Coastguard Worker Snapshot takeSnapshot() const { 259*d57664e9SAndroid Build Coastguard Worker return Snapshot(mMeshSpec, mMode, mBufferData, mUniformBuilder.fUniforms, mBounds); 260*d57664e9SAndroid Build Coastguard Worker } 261*d57664e9SAndroid Build Coastguard Worker uniformBuilder()262*d57664e9SAndroid Build Coastguard Worker MeshUniformBuilder* uniformBuilder() { return &mUniformBuilder; } 263*d57664e9SAndroid Build Coastguard Worker 264*d57664e9SAndroid Build Coastguard Worker private: 265*d57664e9SAndroid Build Coastguard Worker sk_sp<SkMeshSpecification> mMeshSpec; 266*d57664e9SAndroid Build Coastguard Worker SkMesh::Mode mMode; 267*d57664e9SAndroid Build Coastguard Worker std::shared_ptr<MeshBufferData> mBufferData; 268*d57664e9SAndroid Build Coastguard Worker MeshUniformBuilder mUniformBuilder; 269*d57664e9SAndroid Build Coastguard Worker SkRect mBounds; 270*d57664e9SAndroid Build Coastguard Worker }; 271*d57664e9SAndroid Build Coastguard Worker 272*d57664e9SAndroid Build Coastguard Worker } // namespace android 273*d57664e9SAndroid Build Coastguard Worker 274*d57664e9SAndroid Build Coastguard Worker #endif // MESH_H_ 275