Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Unified Diff: src/gpu/gl/GrGpuGL.h

Issue 12533007: Use vertex array objects on core profiles. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Use vertex array objects on core profiles. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLVertexArray.cpp ('k') | src/gpu/gl/GrGpuGL.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGpuGL.h
===================================================================
--- src/gpu/gl/GrGpuGL.h (revision 8015)
+++ src/gpu/gl/GrGpuGL.h (working copy)
@@ -20,6 +20,7 @@
#include "GrGLProgram.h"
#include "GrGLStencilBuffer.h"
#include "GrGLTexture.h"
+#include "GrGLVertexArray.h"
#include "GrGLVertexBuffer.h"
#include "../GrTHashCache.h"
@@ -54,11 +55,29 @@
const GrGLCaps& glCaps() const { return fGLContext.info().caps(); }
- // Callbacks to update state tracking when related GL objects are bound or deleted
- void notifyVertexBufferBind(GrGLuint id);
- void notifyVertexBufferDelete(GrGLuint id);
- void notifyIndexBufferBind(GrGLuint id);
- void notifyIndexBufferDelete(GrGLuint id);
+ // These functions should be used to bind GL objects. They track the GL state and skip redundant
+ // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
+ void bindVertexArray(GrGLuint id) {
+ fHWGeometryState.setVertexArrayID(this, id);
+ }
+ void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
+ fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
+ }
+ void bindVertexBuffer(GrGLuint id) {
+ fHWGeometryState.setVertexBufferID(this, id);
+ }
+
+ // These callbacks update state tracking when GL objects are deleted. They are called from
+ // GrGLResource onRelease functions.
+ void notifyVertexBufferDelete(GrGLuint id) {
+ fHWGeometryState.notifyVertexBufferDelete(id);
+ }
+ void notifyIndexBufferDelete(GrGLuint id) {
+ fHWGeometryState.notifyIndexBufferDelete(id);
+ }
+ void notifyVertexArrayDelete(GrGLuint id) {
jvanverth1 2013/03/07 16:17:44 Match the order of the notify*Delete methods with
bsalomon 2013/03/07 16:25:07 will do before landing.
+ fHWGeometryState.notifyVertexArrayDelete(id);
+ }
void notifyTextureDelete(GrGLTexture* texture);
void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
@@ -121,12 +140,6 @@
// an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
// index is relative to the returned offset.
void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
- // binds appropriate vertex and index buffers. It also returns offsets for the vertex and index
- // buffers. These offsets account for placement within a pool buffer or CPU-side addresses for
- // use with buffer 0. They do not account for start values in the DrawInfo (which is not passed
- // here). The vertex buffer that contains the vertex data is returned. It is not necessarily
- // bound.
- GrGLVertexBuffer* setBuffers(bool indexed, size_t* vertexOffsetInBytes, size_t* indexOffsetInBytes);
// Subclasses should call this to flush the blend state.
// The params should be the final coefficients to apply
@@ -268,134 +281,104 @@
*/
class HWGeometryState {
public:
- HWGeometryState() { fAttribArrayCount = 0; this->invalidate();}
+ HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
+
+ ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
- void setMaxAttribArrays(int max) {
- fAttribArrayCount = max;
- fAttribArrays.reset(max);
- for (int i = 0; i < fAttribArrayCount; ++i) {
- fAttribArrays[i].invalidate();
+ void invalidate() {
+ fBoundVertexArrayIDIsValid = false;
+ fBoundVertexBufferIDIsValid = false;
+ fDefaultVertexArrayBoundIndexBufferID = false;
+ fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
+ fDefaultVertexArrayAttribState.invalidate();
+ }
+
+ void notifyVertexArrayDelete(GrGLuint id) {
+ if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
+ // Does implicit bind to 0
+ fBoundVertexArrayID = 0;
}
}
- void invalidate() {
- fBoundVertexBufferIDIsValid = false;
- fBoundIndexBufferIDIsValid = false;
- for (int i = 0; i < fAttribArrayCount; ++i) {
- fAttribArrays[i].invalidate();
+ void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
+ if (!gpu->glCaps().vertexArrayObjectSupport()) {
+ GrAssert(0 == arrayID);
+ return;
}
+ if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
+ GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
+ fBoundVertexArrayIDIsValid = true;
+ fBoundVertexArrayID = arrayID;
+ }
}
void notifyVertexBufferDelete(GrGLuint id) {
- if (0 != id) {
- if (this->isVertexBufferIDBound(id)) {
- // deleting bound buffer does implied bind to 0
- this->setVertexBufferID(0);
- }
- for (int i = 0; i < fAttribArrayCount; ++i) {
- if (fAttribArrays[i].isVertexBufferIDBound(id)) {
- fAttribArrays[i].invalidate();
- }
- }
+ if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
+ fBoundVertexBufferID = 0;
}
+ if (NULL != fVBOVertexArray) {
+ fVBOVertexArray->notifyVertexBufferDelete(id);
+ }
+ fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
}
void notifyIndexBufferDelete(GrGLuint id) {
- if (0 != id) {
- if (this->isIndexBufferIDBound(id)) {
- // deleting bound buffer does implied bind to 0
- this->setIndexBufferID(0);
- }
+ if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
+ id == fDefaultVertexArrayBoundIndexBufferID) {
+ fDefaultVertexArrayBoundIndexBufferID = 0;
}
+ if (NULL != fVBOVertexArray) {
+ fVBOVertexArray->notifyIndexBufferDelete(id);
+ }
}
- void setVertexBufferID(GrGLuint id) {
- fBoundVertexBufferIDIsValid = true;
- fBoundVertexBufferID = id;
+ void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
+ if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
+ GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
+ fBoundVertexBufferIDIsValid = true;
+ fBoundVertexBufferID = id;
+ }
}
- void setIndexBufferID(GrGLuint id) {
- fBoundIndexBufferIDIsValid = true;
- fBoundIndexBufferID = id;
- }
-
- bool isVertexBufferIDBound(GrGLuint id) const {
- return fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID;
- }
-
- bool isIndexBufferIDBound(GrGLuint id) const {
- return fBoundIndexBufferIDIsValid && id == fBoundIndexBufferID;
- }
-
- void setAttribArray(const GrGpuGL* gpu,
- int index,
- GrGLVertexBuffer* vertexBuffer,
- GrGLint size,
- GrGLenum type,
- GrGLboolean normalized,
- GrGLsizei stride,
- GrGLvoid* offset) {
- GrAssert(index >= 0 && index < fAttribArrayCount);
- AttribArray* attrib = fAttribArrays.get() + index;
- attrib->set(gpu, this, index, vertexBuffer, size, type, normalized, stride, offset);
- }
-
- void disableUnusedAttribArrays(const GrGpuGL* gpu,
- uint32_t usedAttribIndexMask) {
- for (int i = 0; i < fAttribArrayCount; ++i) {
- if (!(usedAttribIndexMask & (1 << i))) {
- fAttribArrays[i].disable(gpu, i);
- }
+ /**
+ * Binds the default vertex array and binds the index buffer. This is used when binding
+ * an index buffer in order to update it.
+ */
+ void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
+ this->setVertexArrayID(gpu, 0);
+ if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
+ id != fDefaultVertexArrayBoundIndexBufferID) {
+ GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
+ fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
+ fDefaultVertexArrayBoundIndexBufferID = id;
}
}
+ /**
+ * Binds the vertex array object that should be used to render from the vertex buffer.
+ * The vertex array is bound and its attrib array state object is returned. The vertex
+ * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
+ * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
+ */
+ GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
+ const GrGLVertexBuffer* vbuffer,
+ const GrGLIndexBuffer* ibuffer);
+
private:
+ GrGLuint fBoundVertexArrayID;
GrGLuint fBoundVertexBufferID;
- GrGLuint fBoundIndexBufferID;
+ bool fBoundVertexArrayIDIsValid;
bool fBoundVertexBufferIDIsValid;
- bool fBoundIndexBufferIDIsValid;
- struct AttribArray {
- public:
- void set(const GrGpuGL* gpu,
- HWGeometryState* geoState,
- int index,
- GrGLVertexBuffer* vertexBuffer,
- GrGLint size,
- GrGLenum type,
- GrGLboolean normalized,
- GrGLsizei stride,
- GrGLvoid* offset);
+ GrGLuint fDefaultVertexArrayBoundIndexBufferID;
+ bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
+ // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
+ // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
+ // GrGpuGL.
+ GrGLAttribArrayState fDefaultVertexArrayAttribState;
- void disable(const GrGpuGL* gpu, int index) {
- if (!fEnableIsValid || fEnabled) {
- GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(index));
- fEnableIsValid = true;
- fEnabled = false;
- }
- }
-
- void invalidate() {
- fEnableIsValid = false;
- fAttribPointerIsValid = false;
- }
-
- bool isVertexBufferIDBound(GrGLuint id) const {
- return fAttribPointerIsValid && id == fVertexBufferID;
- }
- private:
- bool fEnableIsValid;
- bool fAttribPointerIsValid;
- bool fEnabled;
- GrGLuint fVertexBufferID;
- GrGLint fSize;
- GrGLenum fType;
- GrGLboolean fNormalized;
- GrGLsizei fStride;
- GrGLvoid* fOffset;
- };
- SkAutoTArray<AttribArray> fAttribArrays;
- int fAttribArrayCount;
+ // This is used when we're using a core profile and the vertices are in a VBO.
+ GrGLVertexArray* fVBOVertexArray;
} fHWGeometryState;
struct {
« no previous file with comments | « src/gpu/gl/GrGLVertexArray.cpp ('k') | src/gpu/gl/GrGpuGL.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698