Move GrBatchFlushState from GrDrawTarget to GrDrawingManager

This CL:
  moves the flushState
  disables immediate mode (it was proving difficult to implement)
  also moves the program unit test to the drawing manager

BUG=skia:4094
TBR=bsalomon@google.com

Review URL: https://codereview.chromium.org/1437843002
This commit is contained in:
robertphillips 2015-11-11 12:01:09 -08:00 committed by Commit bot
parent 084db25d47
commit a13e202563
9 changed files with 60 additions and 57 deletions

View File

@ -12,7 +12,6 @@
#if SK_SUPPORT_GPU
#include "GrBatchFlushState.h"
#include "GrContext.h"
#include "GrPathUtils.h"
#include "GrTest.h"

View File

@ -12,7 +12,6 @@
#if SK_SUPPORT_GPU
#include "GrBatchFlushState.h"
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h"

View File

@ -399,6 +399,7 @@ private:
// TODO: have the CMM use drawContexts and rm this friending
friend class GrClipMaskManager; // the CMM is friended just so it can call 'drawingManager'
friend class GrDrawingManager; // for access to drawingManager for ProgramUnitTest
GrDrawingManager* drawingManager() { return fDrawingManager; }
GrContext(); // init must be called after the constructor.

View File

@ -86,9 +86,7 @@ void GrContext::initCommon(const GrContextOptions& options) {
fDidTestPMConversions = false;
GrDrawTarget::Options dtOptions;
dtOptions.fImmediateMode = options.fImmediateMode;
fDrawingManager.reset(new GrDrawingManager(this, dtOptions));
fDrawingManager.reset(new GrDrawingManager(this));
// GrBatchFontCache will eventually replace GrFontCache
fBatchFontCache = new GrBatchFontCache(this);

View File

@ -32,14 +32,11 @@
////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider,
const Options& options)
GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider)
: fGpu(SkRef(gpu))
, fResourceProvider(resourceProvider)
, fFlushState(fGpu, fResourceProvider)
, fFlushing(false)
, fFlags(0)
, fOptions(options)
, fRenderTarget(rt) {
// TODO: Stop extracting the context (currently needed by GrClipMaskManager)
fContext = fGpu->getContext();
@ -176,7 +173,7 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
return true;
}
void GrDrawTarget::flush() {
void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) {
if (fFlushing) {
return;
}
@ -190,26 +187,21 @@ void GrDrawTarget::flush() {
// Loop over the batches that haven't yet generated their geometry
for (int i = 0; i < fBatches.count(); ++i) {
fBatches[i]->prepare(&fFlushState);
fBatches[i]->prepare(flushState);
}
}
// Upload all data to the GPU
fFlushState.preIssueDraws();
void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) {
// Draw all the generated geometry.
for (int i = 0; i < fBatches.count(); ++i) {
fBatches[i]->draw(&fFlushState);
fBatches[i]->draw(flushState);
}
SkASSERT(fFlushState.lastFlushedToken() == fFlushState.currentToken());
this->reset();
fFlushing = false;
}
void GrDrawTarget::reset() {
fBatches.reset();
fFlushState.reset();
}
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) {
@ -481,8 +473,6 @@ template <class Left, class Right> static bool intersect(const Left& a, const Ri
void GrDrawTarget::recordBatch(GrBatch* batch) {
// A closed drawTarget should never receive new/more batches
SkASSERT(!this->isClosed());
// Should never have batches queued up when in immediate mode.
SkASSERT(!fOptions.fImmediateMode || !fBatches.count());
// Check if there is a Batch Draw we can batch with by linearly searching back until we either
// 1) check every draw
@ -531,9 +521,6 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
GrBATCH_INFO("\t\tFirstBatch\n");
}
fBatches.push_back().reset(SkRef(batch));
if (fOptions.fImmediateMode) {
this->flush();
}
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -8,7 +8,6 @@
#ifndef GrDrawTarget_DEFINED
#define GrDrawTarget_DEFINED
#include "GrBatchFlushState.h"
#include "GrClip.h"
#include "GrClipMaskManager.h"
#include "GrContext.h"
@ -44,13 +43,9 @@ class GrPathRangeDraw;
class GrDrawTarget final : public SkRefCnt {
public:
struct Options {
bool fImmediateMode;
};
// The context may not be fully constructed and should not be used during GrDrawTarget
// construction.
GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider*, const Options& options);
GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider*);
~GrDrawTarget() override;
@ -90,10 +85,10 @@ public:
void reset();
/**
* This plays any queued up draws to its GrGpu target. It also resets this object (i.e. flushing
* is destructive).
* Together these two functions flush all queued up draws to the Gpu.
*/
void flush();
void prepareBatches(GrBatchFlushState* flushState);
void drawBatches(GrBatchFlushState* flushState);
/**
* Gets the capabilities of the draw target.
@ -210,8 +205,6 @@ public:
const SkIRect& srcRect,
const SkIPoint& dstPoint);
bool programUnitTest(GrContext* owner, int maxStages);
/** Provides access to internal functions to GrClipMaskManager without friending all of
GrDrawTarget to CMM. */
class CMMAccess {
@ -313,12 +306,10 @@ private:
GrContext* fContext;
GrGpu* fGpu;
GrResourceProvider* fResourceProvider;
GrBatchFlushState fFlushState;
bool fFlushing;
SkDEBUGCODE(int fDebugID;)
uint32_t fFlags;
Options fOptions;
// 'this' drawTarget relies on the output of the drawTargets in 'fDependencies'
SkTDArray<GrDrawTarget*> fDependencies;

View File

@ -58,6 +58,7 @@ void GrDrawingManager::reset() {
for (int i = 0; i < fDrawTargets.count(); ++i) {
fDrawTargets[i]->reset();
}
fFlushState.reset();
}
void GrDrawingManager::flush() {
@ -65,10 +66,24 @@ void GrDrawingManager::flush() {
SkTTopoSort<GrDrawTarget, GrDrawTarget::TopoSortTraits>(&fDrawTargets);
SkASSERT(result);
#if 0
for (int i = 0; i < fDrawTargets.count(); ++i) {
//SkDEBUGCODE(fDrawTargets[i]->dump();)
fDrawTargets[i]->flush();
SkDEBUGCODE(fDrawTargets[i]->dump();)
}
#endif
for (int i = 0; i < fDrawTargets.count(); ++i) {
fDrawTargets[i]->prepareBatches(&fFlushState);
}
// Upload all data to the GPU
fFlushState.preIssueDraws();
for (int i = 0; i < fDrawTargets.count(); ++i) {
fDrawTargets[i]->drawBatches(&fFlushState);
}
SkASSERT(fFlushState.lastFlushedToken() == fFlushState.currentToken());
#ifndef ENABLE_MDB
// When MDB is disabled we keep reusing the same drawTarget
@ -77,6 +92,11 @@ void GrDrawingManager::flush() {
fDrawTargets[0]->resetFlag(GrDrawTarget::kWasOutput_Flag);
}
#endif
for (int i = 0; i < fDrawTargets.count(); ++i) {
fDrawTargets[i]->reset();
}
fFlushState.reset();
}
GrTextContext* GrDrawingManager::textContext(const SkSurfaceProps& props,
@ -119,8 +139,7 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
}
#endif
GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider(),
fOptions);
GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider());
*fDrawTargets.append() = dt;

View File

@ -9,6 +9,7 @@
#define GrDrawingManager_DEFINED
#include "GrDrawTarget.h"
#include "GrBatchFlushState.h"
#include "GrPathRendererChain.h"
#include "GrPathRenderer.h"
#include "SkTDArray.h"
@ -49,14 +50,16 @@ public:
GrPathRendererChain::DrawType drawType,
GrPathRenderer::StencilSupport* stencilSupport = NULL);
static bool ProgramUnitTest(GrContext* context, GrDrawTarget* drawTarget, int maxStages);
private:
GrDrawingManager(GrContext* context, GrDrawTarget::Options options)
GrDrawingManager(GrContext* context)
: fContext(context)
, fAbandoned(false)
, fOptions(options)
, fNVPRTextContext(nullptr)
, fPathRendererChain(nullptr)
, fSoftwarePathRenderer(nullptr) {
, fSoftwarePathRenderer(nullptr)
, fFlushState(context->getGpu(), context->resourceProvider()) {
sk_bzero(fTextContexts, sizeof(fTextContexts));
}
@ -74,13 +77,14 @@ private:
bool fAbandoned;
SkTDArray<GrDrawTarget*> fDrawTargets;
GrDrawTarget::Options fOptions;
GrTextContext* fNVPRTextContext;
GrTextContext* fTextContexts[kNumPixelGeometries][kNumDFTOptions];
GrPathRendererChain* fPathRendererChain;
GrSoftwarePathRenderer* fSoftwarePathRenderer;
GrBatchFlushState fFlushState;
};
#endif

View File

@ -15,6 +15,7 @@
#include "GrAutoLocaleSetter.h"
#include "GrBatchTest.h"
#include "GrContextFactory.h"
#include "GrDrawingManager.h"
#include "GrInvariantOutput.h"
#include "GrPipeline.h"
#include "GrResourceProvider.h"
@ -300,7 +301,10 @@ static void set_random_stencil(GrPipelineBuilder* pipelineBuilder, SkRandom* ran
}
}
bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) {
bool GrDrawingManager::ProgramUnitTest(GrContext* context, GrDrawTarget* drawTarget, int maxStages) {
GrDrawingManager* drawingManager = context->drawingManager();
// setup dummy textures
GrSurfaceDesc dummyDesc;
dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag;
@ -334,7 +338,7 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) {
for (int t = 0; t < NUM_TESTS; t++) {
// setup random render target(can fail)
SkAutoTUnref<GrRenderTarget> rt(random_render_target(
context->textureProvider(), &random, this->caps()));
context->textureProvider(), &random, context->caps()));
if (!rt.get()) {
SkDebugf("Could not allocate render target");
return false;
@ -347,16 +351,16 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) {
SkAutoTUnref<GrDrawBatch> batch(GrRandomDrawBatch(&random, context));
SkASSERT(batch);
GrProcessorTestData ptd(&random, context, fGpu->caps(), dummyTextures);
GrProcessorTestData ptd(&random, context, context->caps(), dummyTextures);
set_random_color_coverage_stages(&pipelineBuilder, &ptd, maxStages);
set_random_xpf(&pipelineBuilder, &ptd);
set_random_state(&pipelineBuilder, &random);
set_random_stencil(&pipelineBuilder, &random);
this->drawBatch(pipelineBuilder, batch);
drawTarget->drawBatch(pipelineBuilder, batch);
}
// Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
this->flush();
drawingManager->flush();
// Validate that GrFPs work correctly without an input.
GrSurfaceDesc rtDesc;
@ -365,14 +369,14 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) {
rtDesc.fFlags = kRenderTarget_GrSurfaceFlag;
rtDesc.fConfig = kRGBA_8888_GrPixelConfig;
SkAutoTUnref<GrRenderTarget> rt(
fContext->textureProvider()->createTexture(rtDesc, false)->asRenderTarget());
context->textureProvider()->createTexture(rtDesc, false)->asRenderTarget());
int fpFactoryCnt = GrProcessorTestFactory<GrFragmentProcessor>::Count();
for (int i = 0; i < fpFactoryCnt; ++i) {
// Since FP factories internally randomize, call each 10 times.
for (int j = 0; j < 10; ++j) {
SkAutoTUnref<GrDrawBatch> batch(GrRandomDrawBatch(&random, context));
SkASSERT(batch);
GrProcessorTestData ptd(&random, context, this->caps(), dummyTextures);
GrProcessorTestData ptd(&random, context, context->caps(), dummyTextures);
GrPipelineBuilder builder;
builder.setXPFactory(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
builder.setRenderTarget(rt);
@ -384,8 +388,8 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) {
BlockInputFragmentProcessor::Create(fp));
builder.addColorFragmentProcessor(blockFP);
this->drawBatch(builder, batch);
this->flush();
drawTarget->drawBatch(builder, batch);
drawingManager->flush();
}
}
@ -438,9 +442,10 @@ DEF_GPUTEST(GLPrograms, reporter, factory) {
maxStages = 2;
}
#endif
GrTestTarget target;
context->getTestTarget(&target);
REPORTER_ASSERT(reporter, target.target()->programUnitTest(context, maxStages));
GrTestTarget testTarget;
context->getTestTarget(&testTarget);
REPORTER_ASSERT(reporter, GrDrawingManager::ProgramUnitTest(
context, testTarget.target(), maxStages));
}
}
}