| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "InstancedRendering.h" |
| |
| #include "InstancedOp.h" |
| #include "GrAppliedClip.h" |
| #include "GrCaps.h" |
| #include "GrGpu.h" |
| #include "GrPipeline.h" |
| #include "GrResourceProvider.h" |
| |
| #include "instanced/InstanceProcessor.h" |
| |
| namespace gr_instanced { |
| |
| |
| InstancedRendering::InstancedRendering(GrGpu* gpu) |
| : fGpu(SkRef(gpu)) |
| SkDEBUGCODE(, fState(State::kRecordingDraws)) { |
| } |
| |
| |
| void InstancedRendering::beginFlush(GrResourceProvider* rp) { |
| #ifdef SK_DEBUG |
| SkASSERT(State::kRecordingDraws == fState); |
| fState = State::kFlushing; |
| #endif |
| |
| if (fTrackedOps.isEmpty()) { |
| return; |
| } |
| |
| if (!fVertexBuffer) { |
| fVertexBuffer.reset(InstanceProcessor::FindOrCreateVertexBuffer(fGpu.get())); |
| if (!fVertexBuffer) { |
| return; |
| } |
| } |
| |
| if (!fIndexBuffer) { |
| fIndexBuffer.reset(InstanceProcessor::FindOrCreateIndex8Buffer(fGpu.get())); |
| if (!fIndexBuffer) { |
| return; |
| } |
| } |
| |
| if (!fParams.empty()) { |
| fParamsBuffer.reset(rp->createBuffer(fParams.count() * sizeof(ParamsTexel), |
| kTexel_GrBufferType, kDynamic_GrAccessPattern, |
| GrResourceProvider::kNoPendingIO_Flag | |
| GrResourceProvider::kRequireGpuMemory_Flag, |
| fParams.begin())); |
| if (!fParamsBuffer) { |
| return; |
| } |
| } |
| |
| this->onBeginFlush(rp); |
| } |
| |
| void InstancedRendering::draw(const GrPipeline& pipeline, |
| OpInfo info, |
| const InstancedOp* baseOp) { |
| InstanceProcessor instProc(info, fParamsBuffer.get()); |
| |
| this->onDraw(pipeline, instProc, baseOp); |
| } |
| |
| void InstancedRendering::endFlush() { |
| // The caller is expected to delete all tracked ops (i.e. ops whose applyPipelineOptimizations |
| // method has been called) before ending the flush. |
| SkASSERT(fTrackedOps.isEmpty()); |
| fParams.reset(); |
| fParamsBuffer.reset(); |
| this->onEndFlush(); |
| SkDEBUGCODE(fState = State::kRecordingDraws;) |
| // Hold on to the shape coords and index buffers. |
| } |
| |
| void InstancedRendering::resetGpuResources(ResetType resetType) { |
| fVertexBuffer.reset(); |
| fIndexBuffer.reset(); |
| fParamsBuffer.reset(); |
| this->onResetGpuResources(resetType); |
| } |
| |
| int InstancedRendering::addOpParams(InstancedOp* op) { |
| if (op->fParams.empty()) { |
| return 0; |
| } |
| |
| SkASSERT(fParams.count() < (int)kParamsIdx_InfoMask); // TODO: cleaner. |
| int count = fParams.count(); |
| fParams.push_back_n(op->fParams.count(), op->fParams.begin()); |
| return count; |
| } |
| } |