blob: 9b52837dd46d22a1b89e919209b4d4f37f6e0fe7 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrTargetCommands_DEFINED
#define GrTargetCommands_DEFINED
#include "GrDrawTarget.h"
#include "GrPath.h"
#include "GrPendingProgramElement.h"
#include "GrPrimitiveProcessor.h"
#include "GrRenderTarget.h"
#include "GrTRecorder.h"
#include "batches/GrBatch.h"
#include "SkRect.h"
class GrResourceProvider;
class GrBatchFlushState;
// TODO: Convert all commands into GrBatch and remove this class.
class GrTargetCommands : ::SkNoncopyable {
public:
GrTargetCommands() : fCmdBuffer(kCmdBufferInitialSizeInBytes), fLastFlushToken(0) {}
class Cmd : ::SkNoncopyable {
public:
enum CmdType {
kDrawPath_CmdType = 2,
kDrawPaths_CmdType = 3,
kDrawBatch_CmdType = 4,
};
Cmd(CmdType type)
: fType(type)
#if GR_BATCH_SPEW
, fUniqueID(GenID(&gUniqueID))
#endif
{}
virtual ~Cmd() {}
virtual void execute(GrBatchFlushState*) = 0;
CmdType type() const { return fType; }
GrBATCH_SPEW(uint32_t uniqueID() const { return fUniqueID;} )
private:
// TODO move this to a common header so it can be shared with GrBatch
static uint32_t GenID(int32_t* idCounter) {
uint32_t id = static_cast<uint32_t>(sk_atomic_inc(idCounter)) + 1;
if (!id) {
SkFAIL("This should never wrap\n");
}
return id;
}
CmdType fType;
GrBATCH_SPEW(uint32_t fUniqueID);
GrBATCH_SPEW(static int32_t gUniqueID;)
};
void reset();
void flush(GrGpu*, GrResourceProvider*);
private:
friend class GrCommandBuilder;
friend class GrBufferedDrawTarget; // This goes away when State becomes just a pipeline
friend class GrReorderCommandBuilder;
typedef GrGpu::DrawArgs DrawArgs;
// TODO: This can be just a pipeline once paths are in batch, and it should live elsewhere
struct StateForPathDraw : public SkNVRefCnt<StateForPathDraw> {
// TODO get rid of the prim proc parameter when we use batch everywhere
StateForPathDraw(const GrPrimitiveProcessor* primProc = NULL)
: fPrimitiveProcessor(primProc)
, fCompiled(false) {}
~StateForPathDraw() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); }
// This function is only for getting the location in memory where we will create our
// pipeline object.
void* pipelineLocation() { return fPipeline.get(); }
const GrPipeline* getPipeline() const {
return reinterpret_cast<const GrPipeline*>(fPipeline.get());
}
GrRenderTarget* getRenderTarget() const {
return this->getPipeline()->getRenderTarget();
}
const GrXferProcessor* getXferProcessor() const {
return this->getPipeline()->getXferProcessor();
}
void operator delete(void* p) {}
void* operator new(size_t) {
SkFAIL("All States are created by placement new.");
return sk_malloc_throw(0);
}
void* operator new(size_t, void* p) { return p; }
void operator delete(void* target, void* placement) {
::operator delete(target, placement);
}
typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
ProgramPrimitiveProcessor fPrimitiveProcessor;
SkAlignedSStorage<sizeof(GrPipeline)> fPipeline;
GrProgramDesc fDesc;
GrBatchTracker fBatchTracker;
bool fCompiled;
};
// TODO remove this when State is just a pipeline
friend SkNVRefCnt<StateForPathDraw>;
struct DrawPath : public Cmd {
DrawPath(StateForPathDraw* state, const GrPath* path)
: Cmd(kDrawPath_CmdType)
, fState(SkRef(state))
, fPath(path) {}
const GrPath* path() const { return fPath.get(); }
void execute(GrBatchFlushState*) override;
SkAutoTUnref<StateForPathDraw> fState;
GrStencilSettings fStencilSettings;
private:
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
};
struct DrawPaths : public Cmd {
DrawPaths(StateForPathDraw* state, const GrPathRange* pathRange)
: Cmd(kDrawPaths_CmdType)
, fState(SkRef(state))
, fPathRange(pathRange) {}
const GrPathRange* pathRange() const { return fPathRange.get(); }
void execute(GrBatchFlushState*) override;
SkAutoTUnref<StateForPathDraw> fState;
char* fIndices;
GrDrawTarget::PathIndexType fIndexType;
float* fTransforms;
GrDrawTarget::PathTransformType fTransformType;
int fCount;
GrStencilSettings fStencilSettings;
private:
GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
};
struct DrawBatch : public Cmd {
DrawBatch(GrBatch* batch)
: Cmd(kDrawBatch_CmdType)
, fBatch(SkRef(batch)){
SkASSERT(!batch->isUsed());
}
GrBatch* batch() { return fBatch; }
void execute(GrBatchFlushState*) override;
private:
SkAutoTUnref<GrBatch> fBatch;
};
static const int kCmdBufferInitialSizeInBytes = 8 * 1024;
typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
CmdBuffer* cmdBuffer() { return &fCmdBuffer; }
CmdBuffer fCmdBuffer;
GrBatchToken fLastFlushToken;
};
#endif