Index: src/gpu/GrBufferedDrawTarget.cpp |
diff --git a/src/gpu/GrBufferedDrawTarget.cpp b/src/gpu/GrBufferedDrawTarget.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14a6ba881ef24cc3eee35cd6ab2a63bd96e1eb01 |
--- /dev/null |
+++ b/src/gpu/GrBufferedDrawTarget.cpp |
@@ -0,0 +1,95 @@ |
+/* |
+ * Copyright 2011 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "GrBufferedDrawTarget.h" |
+ |
+// We will use the reordering buffer, unless we have NVPR. |
+// TODO move NVPR to batch so we can reorder |
+static inline bool allow_reordering(const GrCaps* caps) { |
+ return caps && caps->shaderCaps() && !caps->shaderCaps()->pathRenderingSupport(); |
+} |
+ |
+GrBufferedDrawTarget::GrBufferedDrawTarget(GrDrawContext* dc, GrRenderTarget* rt, GrContext* context) |
+ : INHERITED(dc, rt, context) |
+ , fCommands(GrCommandBuilder::Create(context->foo(), context->getGpu(), allow_reordering(context->caps()), rt)) |
+ , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) |
+ , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) |
+ , fPipelineBuffer(kPipelineBufferMinReserve) |
+ , fDrawID(0) { |
+} |
+ |
+GrBufferedDrawTarget::~GrBufferedDrawTarget() { |
+ this->reset(); |
+} |
+ |
+void GrBufferedDrawTarget::onDrawBatch(GrBatch* batch) { |
+ fCommands->recordDrawBatch(batch, *this->caps()); |
+} |
+ |
+void GrBufferedDrawTarget::onDrawPaths(const GrPathProcessor* pathProc, |
+ const GrPathRange* pathRange, |
+ const void* indices, |
+ PathIndexType indexType, |
+ const float transformValues[], |
+ PathTransformType transformType, |
+ int count, |
+ const GrStencilSettings& stencilSettings, |
+ const PipelineInfo& pipelineInfo) { |
+ GrPipelineOptimizations opts; |
+ StateForPathDraw* state = this->createStateForPathDraw(pathProc, pipelineInfo, &opts); |
+ if (!state) { |
+ return; |
+ } |
+ fCommands->recordDrawPaths(state, this, pathProc, pathRange, indices, indexType, |
+ transformValues, transformType, count, stencilSettings, |
+ opts); |
+} |
+ |
+void GrBufferedDrawTarget::onReset() { |
+ fCommands->reset(); |
+ fPathIndexBuffer.rewind(); |
+ fPathTransformBuffer.rewind(); |
+ |
+ fPrevState.reset(nullptr); |
+ // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first. |
+ // Furthermore, we have to reset fCommands before fPipelineBuffer too. |
+ if (fDrawID % kPipelineBufferHighWaterMark) { |
+ fPipelineBuffer.rewind(); |
+ } else { |
+ fPipelineBuffer.reset(); |
+ } |
+} |
+ |
+void GrBufferedDrawTarget::onFlush() { |
+ fCommands->flush(this->getGpu(), this->getContext()->resourceProvider()); |
+ ++fDrawID; |
+} |
+ |
+GrTargetCommands::StateForPathDraw* |
+GrBufferedDrawTarget::createStateForPathDraw(const GrPrimitiveProcessor* primProc, |
+ const GrDrawTarget::PipelineInfo& pipelineInfo, |
+ GrPipelineOptimizations* opts) { |
+ StateForPathDraw* state = this->allocState(primProc); |
+ if (!GrPipeline::CreateAt(state->pipelineLocation(), pipelineInfo.pipelineCreateArgs(), opts)) { |
+ this->unallocState(state); |
+ return nullptr; |
+ } |
+ |
+ state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker, *opts); |
+ |
+ if (fPrevState && fPrevState->fPrimitiveProcessor.get() && |
+ fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, |
+ *state->fPrimitiveProcessor, |
+ state->fBatchTracker) && |
+ GrPipeline::AreEqual(*fPrevState->getPipeline(), *state->getPipeline(), false)) { |
+ this->unallocState(state); |
+ } else { |
+ fPrevState.reset(state); |
+ } |
+ |
+ return fPrevState; |
+} |