blob: cb4a1de63d298132a453cce691218249aba81ab4 [file] [log] [blame]
csmartdaltona7f29642016-07-07 08:49:11 -07001/*
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"
Robert Phillipse3302df2017-04-24 07:31:02 -04009
10#include "InstancedOp.h"
Brian Salomon13071c52017-03-29 21:28:20 -040011#include "GrAppliedClip.h"
robertphillips5fa7f302016-07-21 09:21:04 -070012#include "GrCaps.h"
Robert Phillips646e4292017-06-13 12:44:56 -040013#include "GrGpu.h"
csmartdaltona7f29642016-07-07 08:49:11 -070014#include "GrPipeline.h"
15#include "GrResourceProvider.h"
Robert Phillipse3302df2017-04-24 07:31:02 -040016
csmartdaltona7f29642016-07-07 08:49:11 -070017#include "instanced/InstanceProcessor.h"
18
19namespace gr_instanced {
20
Robert Phillipse3302df2017-04-24 07:31:02 -040021
csmartdaltone0d36292016-07-29 08:14:20 -070022InstancedRendering::InstancedRendering(GrGpu* gpu)
Robert Phillipse3302df2017-04-24 07:31:02 -040023 : fGpu(SkRef(gpu))
24 SkDEBUGCODE(, fState(State::kRecordingDraws)) {
csmartdaltona7f29642016-07-07 08:49:11 -070025}
26
Robert Phillipsfbcef6e2017-06-15 12:07:18 -040027InstancedRendering::~InstancedRendering() {
28 SkASSERT(State::kRecordingDraws == fState);
29}
csmartdaltona7f29642016-07-07 08:49:11 -070030
31void InstancedRendering::beginFlush(GrResourceProvider* rp) {
Robert Phillipse3302df2017-04-24 07:31:02 -040032#ifdef SK_DEBUG
csmartdaltona7f29642016-07-07 08:49:11 -070033 SkASSERT(State::kRecordingDraws == fState);
34 fState = State::kFlushing;
Robert Phillipse3302df2017-04-24 07:31:02 -040035#endif
csmartdaltona7f29642016-07-07 08:49:11 -070036
Brian Salomon99ad1642016-12-16 09:50:45 -050037 if (fTrackedOps.isEmpty()) {
csmartdaltona7f29642016-07-07 08:49:11 -070038 return;
39 }
40
41 if (!fVertexBuffer) {
Hal Canary144caf52016-11-07 17:57:18 -050042 fVertexBuffer.reset(InstanceProcessor::FindOrCreateVertexBuffer(fGpu.get()));
csmartdaltona7f29642016-07-07 08:49:11 -070043 if (!fVertexBuffer) {
44 return;
45 }
46 }
47
48 if (!fIndexBuffer) {
Hal Canary144caf52016-11-07 17:57:18 -050049 fIndexBuffer.reset(InstanceProcessor::FindOrCreateIndex8Buffer(fGpu.get()));
csmartdaltona7f29642016-07-07 08:49:11 -070050 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,
csmartdalton485a1202016-07-13 10:16:32 -070058 GrResourceProvider::kNoPendingIO_Flag |
59 GrResourceProvider::kRequireGpuMemory_Flag,
csmartdaltona7f29642016-07-07 08:49:11 -070060 fParams.begin()));
61 if (!fParamsBuffer) {
62 return;
63 }
64 }
65
66 this->onBeginFlush(rp);
67}
68
Robert Phillipse3302df2017-04-24 07:31:02 -040069void InstancedRendering::draw(const GrPipeline& pipeline,
70 OpInfo info,
71 const InstancedOp* baseOp) {
72 InstanceProcessor instProc(info, fParamsBuffer.get());
csmartdaltona7f29642016-07-07 08:49:11 -070073
Robert Phillipse3302df2017-04-24 07:31:02 -040074 this->onDraw(pipeline, instProc, baseOp);
csmartdaltona7f29642016-07-07 08:49:11 -070075}
76
77void InstancedRendering::endFlush() {
Brian Salomon92aee3d2016-12-21 09:20:25 -050078 // The caller is expected to delete all tracked ops (i.e. ops whose applyPipelineOptimizations
csmartdaltona7f29642016-07-07 08:49:11 -070079 // method has been called) before ending the flush.
Brian Salomon99ad1642016-12-16 09:50:45 -050080 SkASSERT(fTrackedOps.isEmpty());
csmartdaltona7f29642016-07-07 08:49:11 -070081 fParams.reset();
82 fParamsBuffer.reset();
83 this->onEndFlush();
Robert Phillipse3302df2017-04-24 07:31:02 -040084 SkDEBUGCODE(fState = State::kRecordingDraws;)
csmartdaltona7f29642016-07-07 08:49:11 -070085 // Hold on to the shape coords and index buffers.
86}
87
88void InstancedRendering::resetGpuResources(ResetType resetType) {
89 fVertexBuffer.reset();
90 fIndexBuffer.reset();
91 fParamsBuffer.reset();
92 this->onResetGpuResources(resetType);
93}
94
Robert Phillipse3302df2017-04-24 07:31:02 -040095int 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}
csmartdaltona7f29642016-07-07 08:49:11 -0700105}