1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "InstancedRendering.h"
9
10 #include "InstancedOp.h"
11 #include "GrAppliedClip.h"
12 #include "GrCaps.h"
13 #include "GrGpu.h"
14 #include "GrPipeline.h"
15 #include "GrResourceProvider.h"
16
17 #include "instanced/InstanceProcessor.h"
18
19 namespace gr_instanced {
20
21
InstancedRendering(GrGpu * gpu)22 InstancedRendering::InstancedRendering(GrGpu* gpu)
23 : fGpu(SkRef(gpu))
24 SkDEBUGCODE(, fState(State::kRecordingDraws)) {
25 }
26
~InstancedRendering()27 InstancedRendering::~InstancedRendering() {
28 SkASSERT(State::kRecordingDraws == fState);
29 }
30
beginFlush(GrResourceProvider * rp)31 void InstancedRendering::beginFlush(GrResourceProvider* rp) {
32 #ifdef SK_DEBUG
33 SkASSERT(State::kRecordingDraws == fState);
34 fState = State::kFlushing;
35 #endif
36
37 if (fTrackedOps.isEmpty()) {
38 return;
39 }
40
41 if (!fVertexBuffer) {
42 fVertexBuffer.reset(InstanceProcessor::FindOrCreateVertexBuffer(fGpu.get()));
43 if (!fVertexBuffer) {
44 return;
45 }
46 }
47
48 if (!fIndexBuffer) {
49 fIndexBuffer.reset(InstanceProcessor::FindOrCreateIndex8Buffer(fGpu.get()));
50 if (!fIndexBuffer) {
51 return;
52 }
53 }
54
55 if (!fParams.empty()) {
56 fParamsBuffer.reset(rp->createBuffer(fParams.count() * sizeof(ParamsTexel),
57 kTexel_GrBufferType, kDynamic_GrAccessPattern,
58 GrResourceProvider::kNoPendingIO_Flag |
59 GrResourceProvider::kRequireGpuMemory_Flag,
60 fParams.begin()));
61 if (!fParamsBuffer) {
62 return;
63 }
64 }
65
66 this->onBeginFlush(rp);
67 }
68
draw(const GrPipeline & pipeline,OpInfo info,const InstancedOp * baseOp)69 void InstancedRendering::draw(const GrPipeline& pipeline,
70 OpInfo info,
71 const InstancedOp* baseOp) {
72 InstanceProcessor instProc(info, fParamsBuffer.get());
73
74 this->onDraw(pipeline, instProc, baseOp);
75 }
76
endFlush()77 void InstancedRendering::endFlush() {
78 // The caller is expected to delete all tracked ops (i.e. ops whose applyPipelineOptimizations
79 // method has been called) before ending the flush.
80 SkASSERT(fTrackedOps.isEmpty());
81 fParams.reset();
82 fParamsBuffer.reset();
83 this->onEndFlush();
84 SkDEBUGCODE(fState = State::kRecordingDraws;)
85 // Hold on to the shape coords and index buffers.
86 }
87
resetGpuResources(ResetType resetType)88 void InstancedRendering::resetGpuResources(ResetType resetType) {
89 fVertexBuffer.reset();
90 fIndexBuffer.reset();
91 fParamsBuffer.reset();
92 this->onResetGpuResources(resetType);
93 }
94
addOpParams(InstancedOp * op)95 int InstancedRendering::addOpParams(InstancedOp* op) {
96 if (op->fParams.empty()) {
97 return 0;
98 }
99
100 SkASSERT(fParams.count() < (int)kParamsIdx_InfoMask); // TODO: cleaner.
101 int count = fParams.count();
102 fParams.push_back_n(op->fParams.count(), op->fParams.begin());
103 return count;
104 }
105 }
106