blob: b26cd7294e41a399444be9a1a04bca7c4d04f994 [file] [log] [blame]
/*
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef GrInOrderDrawBuffer_DEFINED
#define GrInOrderDrawBuffer_DEFINED
#include "GrDrawTarget.h"
#include "GrAllocPool.h"
#include "GrAllocator.h"
#include "GrClip.h"
class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
/**
* GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
* draws for eventual playback into a GrGpu. In theory one draw buffer could
* playback into another. When index or vertex buffers are used as geometry
* sources it is the callers the draw buffer only holds references to the
* buffers. It is the callers responsibility to ensure that the data is still
* valid when the draw buffer is played back into a GrGpu. Similarly, it is the
* caller's responsibility to ensure that all referenced textures, buffers,
* and rendertargets are associated in the GrGpu object that the buffer is
* played back into. The buffer requires VB and IB pools to store geometry.
*/
class GrInOrderDrawBuffer : public GrDrawTarget {
public:
/**
* Creates a GrInOrderDrawBuffer
*
* @param vertexPool pool where vertices for queued draws will be saved when
* the vertex source is either reserved or array.
* @param indexPool pool where indices for queued draws will be saved when
* the index source is either reserved or array.
*/
GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool);
virtual ~GrInOrderDrawBuffer();
/**
* Copies the draw state and clip from target to this draw buffer.
*
* @param target the target whose clip and state should be copied.
*/
void initializeDrawStateAndClip(const GrDrawTarget& target);
/**
* Provides the buffer with an index buffer that can be used for quad rendering.
* The buffer may be able to batch consecutive drawRects if this is provided.
* @param indexBuffer index buffer with quad indices.
*/
void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
/**
* Empties the draw buffer of any queued up draws.
*/
void reset();
/**
* plays the queued up draws to another target. Does not empty this buffer so
* that it can be played back multiple times.
* @param target the target to receive the playback
*/
void playback(GrDrawTarget* target);
// overrides from GrDrawTarget
virtual void drawIndexed(GrPrimitiveType primitiveType,
int startVertex,
int startIndex,
int vertexCount,
int indexCount);
virtual void drawNonIndexed(GrPrimitiveType primitiveType,
int startVertex,
int vertexCount);
virtual void drawRect(const GrRect& rect,
const GrMatrix* matrix = NULL,
int stageEnableMask = 0,
const GrRect* srcRects[] = NULL,
const GrMatrix* srcMatrices[] = NULL);
virtual bool geometryHints(GrVertexLayout vertexLayout,
int* vertexCount,
int* indexCount) const;
virtual void clear(const GrIRect* rect, GrColor color);
private:
struct Draw {
GrPrimitiveType fPrimitiveType;
int fStartVertex;
int fStartIndex;
int fVertexCount;
int fIndexCount;
bool fStateChanged;
bool fClipChanged;
GrVertexLayout fVertexLayout;
const GrVertexBuffer* fVertexBuffer;
const GrIndexBuffer* fIndexBuffer;
};
struct Clear {
int fBeforeDrawIdx;
GrIRect fRect;
GrColor fColor;
};
virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
void** vertices,
void** indices);
virtual void onReleaseGeometry();
virtual void clipWillBeSet(const GrClip& newClip);
virtual void onSetVertexSourceToArray(const void* vertexArray,
int vertexCount);
virtual void onSetIndexSourceToArray(const void* indexArray,
int indexCount);
bool needsNewState() const;
bool needsNewClip() const;
void pushState();
void pushClip();
GrTAllocator<Draw> fDraws;
GrTAllocator<SavedDrawState> fStates;
GrTAllocator<Clear> fClears;
GrTAllocator<GrClip> fClips;
bool fClipSet;
GrVertexLayout fLastRectVertexLayout;
const GrIndexBuffer* fQuadIndexBuffer;
int fMaxQuads;
int fCurrQuad;
GrVertexBufferAllocPool& fVertexPool;
const GrVertexBuffer* fCurrPoolVertexBuffer;
int fCurrPoolStartVertex;
GrIndexBufferAllocPool& fIndexPool;
const GrIndexBuffer* fCurrPoolIndexBuffer;
int fCurrPoolStartIndex;
// caller may conservatively over reserve vertices / indices.
// we release unused space back to allocator if possible
size_t fReservedVertexBytes;
size_t fReservedIndexBytes;
size_t fUsedReservedVertexBytes;
size_t fUsedReservedIndexBytes;
enum {
kDrawPreallocCnt = 8,
kStatePreallocCnt = 8,
kClipPreallocCnt = 8,
kClearPreallocCnt = 4,
};
GrAlignedSTStorage<kDrawPreallocCnt, Draw> fDrawStorage;
GrAlignedSTStorage<kStatePreallocCnt, SavedDrawState> fStateStorage;
GrAlignedSTStorage<kClipPreallocCnt, GrClip> fClipStorage;
GrAlignedSTStorage<kClearPreallocCnt, Clear> fClearStorage;
typedef GrDrawTarget INHERITED;
};
#endif