blob: 2f9909bb026ae5bb3329a6f4d7946ecc86cf5291 [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 "GrBatch.h"
#include "GrBatchTarget.h"
#include "GrDrawTarget.h"
#include "GrGpu.h"
#include "GrPath.h"
#include "GrPendingProgramElement.h"
#include "GrRenderTarget.h"
#include "GrTRecorder.h"
#include "SkRect.h"
#include "SkTypes.h"
class GrInOrderDrawBuffer;
class GrTargetCommands : ::SkNoncopyable {
public:
GrTargetCommands(GrGpu* gpu)
: fCmdBuffer(kCmdBufferInitialSizeInBytes)
, fBatchTarget(gpu) {
}
class Cmd : ::SkNoncopyable {
public:
enum CmdType {
kStencilPath_CmdType = 1,
kSetState_CmdType = 2,
kClear_CmdType = 3,
kCopySurface_CmdType = 4,
kDrawPath_CmdType = 5,
kDrawPaths_CmdType = 6,
kDrawBatch_CmdType = 7,
kXferBarrier_CmdType = 8,
};
Cmd(CmdType type) : fMarkerID(-1), fType(type) {}
virtual ~Cmd() {}
virtual void execute(GrGpu*) = 0;
CmdType type() const { return fType; }
// trace markers
bool isTraced() const { return -1 != fMarkerID; }
void setMarkerID(int markerID) { SkASSERT(-1 == fMarkerID); fMarkerID = markerID; }
int markerID() const { return fMarkerID; }
private:
int fMarkerID;
CmdType fType;
};
void reset();
void flush(GrInOrderDrawBuffer*);
private:
friend class GrCommandBuilder;
friend class GrInOrderDrawBuffer; // This goes away when State becomes just a pipeline
friend class GrReorderCommandBuilder;
typedef GrGpu::DrawArgs DrawArgs;
void recordXferBarrierIfNecessary(const GrPipeline&, GrInOrderDrawBuffer*);
// TODO: This can be just a pipeline once paths are in batch, and it should live elsewhere
struct State : public SkNVRefCnt<State> {
// TODO get rid of the prim proc parameter when we use batch everywhere
State(const GrPrimitiveProcessor* primProc = NULL)
: fPrimitiveProcessor(primProc)
, fCompiled(false) {}
~State() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); }
// This function is only for getting the location in memory where we will create our
// pipeline object.
GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(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<State>;
struct StencilPath : public Cmd {
StencilPath(const GrPath* path, GrRenderTarget* rt)
: Cmd(kStencilPath_CmdType)
, fRenderTarget(rt)
, fPath(path) {}
const GrPath* path() const { return fPath.get(); }
void execute(GrGpu*) override;
SkMatrix fViewMatrix;
bool fUseHWAA;
GrStencilSettings fStencil;
GrScissorState fScissor;
private:
GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
};
struct DrawPath : public Cmd {
DrawPath(State* state, const GrPath* path)
: Cmd(kDrawPath_CmdType)
, fState(SkRef(state))
, fPath(path) {}
const GrPath* path() const { return fPath.get(); }
void execute(GrGpu*) override;
SkAutoTUnref<State> fState;
GrStencilSettings fStencilSettings;
private:
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
};
struct DrawPaths : public Cmd {
DrawPaths(State* state, const GrPathRange* pathRange)
: Cmd(kDrawPaths_CmdType)
, fState(SkRef(state))
, fPathRange(pathRange) {}
const GrPathRange* pathRange() const { return fPathRange.get(); }
void execute(GrGpu*) override;
SkAutoTUnref<State> fState;
char* fIndices;
GrDrawTarget::PathIndexType fIndexType;
float* fTransforms;
GrDrawTarget::PathTransformType fTransformType;
int fCount;
GrStencilSettings fStencilSettings;
private:
GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
};
// This is also used to record a discard by setting the color to GrColor_ILLEGAL
struct Clear : public Cmd {
Clear(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
void execute(GrGpu*) override;
SkIRect fRect;
GrColor fColor;
bool fCanIgnoreRect;
private:
GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
};
// This command is ONLY used by the clip mask manager to clear the stencil clip bits
struct ClearStencilClip : public Cmd {
ClearStencilClip(GrRenderTarget* rt) : Cmd(kClear_CmdType), fRenderTarget(rt) {}
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
void execute(GrGpu*) override;
SkIRect fRect;
bool fInsideClip;
private:
GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
};
struct CopySurface : public Cmd {
CopySurface(GrSurface* dst, GrSurface* src)
: Cmd(kCopySurface_CmdType)
, fDst(dst)
, fSrc(src) {
}
GrSurface* dst() const { return fDst.get(); }
GrSurface* src() const { return fSrc.get(); }
void execute(GrGpu*) override;
SkIPoint fDstPoint;
SkIRect fSrcRect;
private:
GrPendingIOResource<GrSurface, kWrite_GrIOType> fDst;
GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc;
};
struct DrawBatch : public Cmd {
DrawBatch(State* state, GrBatch* batch, GrBatchTarget* batchTarget)
: Cmd(kDrawBatch_CmdType)
, fState(SkRef(state))
, fBatch(SkRef(batch))
, fBatchTarget(batchTarget) {
SkASSERT(!batch->isUsed());
}
void execute(GrGpu*) override;
SkAutoTUnref<State> fState;
SkAutoTUnref<GrBatch> fBatch;
private:
GrBatchTarget* fBatchTarget;
};
struct XferBarrier : public Cmd {
XferBarrier(GrRenderTarget* rt)
: Cmd(kXferBarrier_CmdType)
, fRenderTarget(rt) {
}
void execute(GrGpu*) override;
GrXferBarrierType fBarrierType;
private:
GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
};
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; }
GrBatchTarget* batchTarget() { return &fBatchTarget; }
CmdBuffer fCmdBuffer;
GrBatchTarget fBatchTarget;
};
#endif