OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 | 9 |
10 #ifndef GrGpuGL_DEFINED | 10 #ifndef GrGpuGL_DEFINED |
11 #define GrGpuGL_DEFINED | 11 #define GrGpuGL_DEFINED |
12 | 12 |
13 | 13 |
14 #include "GrBinHashKey.h" | 14 #include "GrBinHashKey.h" |
15 #include "GrDrawState.h" | 15 #include "GrDrawState.h" |
16 #include "GrGpu.h" | 16 #include "GrGpu.h" |
17 #include "GrGLContext.h" | 17 #include "GrGLContext.h" |
18 #include "GrGLIndexBuffer.h" | 18 #include "GrGLIndexBuffer.h" |
19 #include "GrGLIRect.h" | 19 #include "GrGLIRect.h" |
20 #include "GrGLProgram.h" | 20 #include "GrGLProgram.h" |
21 #include "GrGLStencilBuffer.h" | 21 #include "GrGLStencilBuffer.h" |
22 #include "GrGLTexture.h" | 22 #include "GrGLTexture.h" |
23 #include "GrGLVertexArray.h" | |
23 #include "GrGLVertexBuffer.h" | 24 #include "GrGLVertexBuffer.h" |
24 #include "../GrTHashCache.h" | 25 #include "../GrTHashCache.h" |
25 | 26 |
26 class GrGpuGL : public GrGpu { | 27 class GrGpuGL : public GrGpu { |
27 public: | 28 public: |
28 GrGpuGL(const GrGLContext& ctx, GrContext* context); | 29 GrGpuGL(const GrGLContext& ctx, GrContext* context); |
29 virtual ~GrGpuGL(); | 30 virtual ~GrGpuGL(); |
30 | 31 |
31 const GrGLInterface* glInterface() const { return fGLContext.interface(); } | 32 const GrGLInterface* glInterface() const { return fGLContext.interface(); } |
32 GrGLBinding glBinding() const { return fGLContext.info().binding(); } | 33 GrGLBinding glBinding() const { return fGLContext.info().binding(); } |
(...skipping 14 matching lines...) Expand all Loading... | |
47 int left, int top, | 48 int left, int top, |
48 int width, int height, | 49 int width, int height, |
49 GrPixelConfig config, | 50 GrPixelConfig config, |
50 size_t rowBytes) const SK_OVERRIDE; | 51 size_t rowBytes) const SK_OVERRIDE; |
51 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; | 52 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; |
52 | 53 |
53 virtual void abandonResources() SK_OVERRIDE; | 54 virtual void abandonResources() SK_OVERRIDE; |
54 | 55 |
55 const GrGLCaps& glCaps() const { return fGLContext.info().caps(); } | 56 const GrGLCaps& glCaps() const { return fGLContext.info().caps(); } |
56 | 57 |
57 // Callbacks to update state tracking when related GL objects are bound or d eleted | 58 // These functions should be used to bind GL objects. They track the GL stat e and skip redundant |
58 void notifyVertexBufferBind(GrGLuint id); | 59 // bindings. Making the equivalent glBind calls directly will confuse the st ate tracking. |
59 void notifyVertexBufferDelete(GrGLuint id); | 60 void bindVertexArray(GrGLuint id) { |
60 void notifyIndexBufferBind(GrGLuint id); | 61 fHWGeometryState.setVertexArrayID(this, id); |
61 void notifyIndexBufferDelete(GrGLuint id); | 62 } |
63 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) { | |
64 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id); | |
65 } | |
66 void bindVertexBuffer(GrGLuint id) { | |
67 fHWGeometryState.setVertexBufferID(this, id); | |
68 } | |
69 | |
70 // These callbacks update state tracking when GL objects are deleted. They a re called from | |
71 // GrGLResource onRelease functions. | |
72 void notifyVertexBufferDelete(GrGLuint id) { | |
73 fHWGeometryState.notifyVertexBufferDelete(id); | |
74 } | |
75 void notifyIndexBufferDelete(GrGLuint id) { | |
76 fHWGeometryState.notifyIndexBufferDelete(id); | |
77 } | |
78 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.
| |
79 fHWGeometryState.notifyVertexArrayDelete(id); | |
80 } | |
62 void notifyTextureDelete(GrGLTexture* texture); | 81 void notifyTextureDelete(GrGLTexture* texture); |
63 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); | 82 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); |
64 | 83 |
65 private: | 84 private: |
66 // GrGpu overrides | 85 // GrGpu overrides |
67 virtual void onResetContext() SK_OVERRIDE; | 86 virtual void onResetContext() SK_OVERRIDE; |
68 | 87 |
69 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, | 88 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, |
70 const void* srcData, | 89 const void* srcData, |
71 size_t rowBytes) SK_OVERRIDE; | 90 size_t rowBytes) SK_OVERRIDE; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 bool insideClip) SK_OVERRIDE; | 133 bool insideClip) SK_OVERRIDE; |
115 virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; | 134 virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; |
116 | 135 |
117 // binds texture unit in GL | 136 // binds texture unit in GL |
118 void setTextureUnit(int unitIdx); | 137 void setTextureUnit(int unitIdx); |
119 | 138 |
120 // Sets up vertex attribute pointers and strides. On return indexOffsetInByt es gives the offset | 139 // Sets up vertex attribute pointers and strides. On return indexOffsetInByt es gives the offset |
121 // an into the index buffer. It does not account for drawInfo.startIndex() b ut rather the start | 140 // an into the index buffer. It does not account for drawInfo.startIndex() b ut rather the start |
122 // index is relative to the returned offset. | 141 // index is relative to the returned offset. |
123 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes); | 142 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes); |
124 // binds appropriate vertex and index buffers. It also returns offsets for t he vertex and index | |
125 // buffers. These offsets account for placement within a pool buffer or CPU- side addresses for | |
126 // use with buffer 0. They do not account for start values in the DrawInfo ( which is not passed | |
127 // here). The vertex buffer that contains the vertex data is returned. It is not necessarily | |
128 // bound. | |
129 GrGLVertexBuffer* setBuffers(bool indexed, size_t* vertexOffsetInBytes, size _t* indexOffsetInBytes); | |
130 | 143 |
131 // Subclasses should call this to flush the blend state. | 144 // Subclasses should call this to flush the blend state. |
132 // The params should be the final coefficients to apply | 145 // The params should be the final coefficients to apply |
133 // (after any blending optimizations or dual source blending considerations | 146 // (after any blending optimizations or dual source blending considerations |
134 // have been accounted for). | 147 // have been accounted for). |
135 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); | 148 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); |
136 | 149 |
137 bool hasExtension(const char* ext) const { return fGLContext.info().hasExten sion(ext); } | 150 bool hasExtension(const char* ext) const { return fGLContext.info().hasExten sion(ext); } |
138 | 151 |
139 const GrGLContext& glContext() const { return fGLContext; } | 152 const GrGLContext& glContext() const { return fGLContext; } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 } | 274 } |
262 } fHWScissorSettings; | 275 } fHWScissorSettings; |
263 | 276 |
264 GrGLIRect fHWViewport; | 277 GrGLIRect fHWViewport; |
265 | 278 |
266 /** | 279 /** |
267 * Tracks bound vertex and index buffers and vertex attrib array state. | 280 * Tracks bound vertex and index buffers and vertex attrib array state. |
268 */ | 281 */ |
269 class HWGeometryState { | 282 class HWGeometryState { |
270 public: | 283 public: |
271 HWGeometryState() { fAttribArrayCount = 0; this->invalidate();} | 284 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); } |
285 | |
286 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); } | |
272 | 287 |
273 void setMaxAttribArrays(int max) { | 288 void invalidate() { |
274 fAttribArrayCount = max; | 289 fBoundVertexArrayIDIsValid = false; |
275 fAttribArrays.reset(max); | 290 fBoundVertexBufferIDIsValid = false; |
276 for (int i = 0; i < fAttribArrayCount; ++i) { | 291 fDefaultVertexArrayBoundIndexBufferID = false; |
277 fAttribArrays[i].invalidate(); | 292 fDefaultVertexArrayBoundIndexBufferIDIsValid = false; |
293 fDefaultVertexArrayAttribState.invalidate(); | |
294 } | |
295 | |
296 void notifyVertexArrayDelete(GrGLuint id) { | |
297 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { | |
298 // Does implicit bind to 0 | |
299 fBoundVertexArrayID = 0; | |
278 } | 300 } |
279 } | 301 } |
280 | 302 |
281 void invalidate() { | 303 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) { |
282 fBoundVertexBufferIDIsValid = false; | 304 if (!gpu->glCaps().vertexArrayObjectSupport()) { |
283 fBoundIndexBufferIDIsValid = false; | 305 GrAssert(0 == arrayID); |
284 for (int i = 0; i < fAttribArrayCount; ++i) { | 306 return; |
285 fAttribArrays[i].invalidate(); | 307 } |
308 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { | |
309 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); | |
310 fBoundVertexArrayIDIsValid = true; | |
311 fBoundVertexArrayID = arrayID; | |
286 } | 312 } |
287 } | 313 } |
288 | 314 |
289 void notifyVertexBufferDelete(GrGLuint id) { | 315 void notifyVertexBufferDelete(GrGLuint id) { |
290 if (0 != id) { | 316 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) { |
291 if (this->isVertexBufferIDBound(id)) { | 317 fBoundVertexBufferID = 0; |
292 // deleting bound buffer does implied bind to 0 | 318 } |
293 this->setVertexBufferID(0); | 319 if (NULL != fVBOVertexArray) { |
294 } | 320 fVBOVertexArray->notifyVertexBufferDelete(id); |
295 for (int i = 0; i < fAttribArrayCount; ++i) { | 321 } |
296 if (fAttribArrays[i].isVertexBufferIDBound(id)) { | 322 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id); |
297 fAttribArrays[i].invalidate(); | 323 } |
298 } | 324 |
299 } | 325 void notifyIndexBufferDelete(GrGLuint id) { |
326 if (fDefaultVertexArrayBoundIndexBufferIDIsValid && | |
327 id == fDefaultVertexArrayBoundIndexBufferID) { | |
328 fDefaultVertexArrayBoundIndexBufferID = 0; | |
329 } | |
330 if (NULL != fVBOVertexArray) { | |
331 fVBOVertexArray->notifyIndexBufferDelete(id); | |
300 } | 332 } |
301 } | 333 } |
302 | 334 |
303 void notifyIndexBufferDelete(GrGLuint id) { | 335 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) { |
304 if (0 != id) { | 336 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) { |
305 if (this->isIndexBufferIDBound(id)) { | 337 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id )); |
306 // deleting bound buffer does implied bind to 0 | 338 fBoundVertexBufferIDIsValid = true; |
307 this->setIndexBufferID(0); | 339 fBoundVertexBufferID = id; |
308 } | |
309 } | 340 } |
310 } | 341 } |
311 | 342 |
312 void setVertexBufferID(GrGLuint id) { | 343 /** |
313 fBoundVertexBufferIDIsValid = true; | 344 * Binds the default vertex array and binds the index buffer. This is us ed when binding |
314 fBoundVertexBufferID = id; | 345 * an index buffer in order to update it. |
315 } | 346 */ |
316 | 347 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) { |
317 void setIndexBufferID(GrGLuint id) { | 348 this->setVertexArrayID(gpu, 0); |
318 fBoundIndexBufferIDIsValid = true; | 349 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid || |
319 fBoundIndexBufferID = id; | 350 id != fDefaultVertexArrayBoundIndexBufferID) { |
320 } | 351 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BU FFER, id)); |
321 | 352 fDefaultVertexArrayBoundIndexBufferIDIsValid = true; |
322 bool isVertexBufferIDBound(GrGLuint id) const { | 353 fDefaultVertexArrayBoundIndexBufferID = id; |
323 return fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID; | |
324 } | |
325 | |
326 bool isIndexBufferIDBound(GrGLuint id) const { | |
327 return fBoundIndexBufferIDIsValid && id == fBoundIndexBufferID; | |
328 } | |
329 | |
330 void setAttribArray(const GrGpuGL* gpu, | |
331 int index, | |
332 GrGLVertexBuffer* vertexBuffer, | |
333 GrGLint size, | |
334 GrGLenum type, | |
335 GrGLboolean normalized, | |
336 GrGLsizei stride, | |
337 GrGLvoid* offset) { | |
338 GrAssert(index >= 0 && index < fAttribArrayCount); | |
339 AttribArray* attrib = fAttribArrays.get() + index; | |
340 attrib->set(gpu, this, index, vertexBuffer, size, type, normalized, stride, offset); | |
341 } | |
342 | |
343 void disableUnusedAttribArrays(const GrGpuGL* gpu, | |
344 uint32_t usedAttribIndexMask) { | |
345 for (int i = 0; i < fAttribArrayCount; ++i) { | |
346 if (!(usedAttribIndexMask & (1 << i))) { | |
347 fAttribArrays[i].disable(gpu, i); | |
348 } | |
349 } | 354 } |
350 } | 355 } |
351 | 356 |
357 /** | |
358 * Binds the vertex array object that should be used to render from the vertex buffer. | |
359 * The vertex array is bound and its attrib array state object is return ed. The vertex | |
360 * buffer is bound. The index buffer (if non-NULL) is bound to the verte x array. The | |
361 * returned GrGLAttribArrayState should be used to set vertex attribute arrays. | |
362 */ | |
363 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu, | |
364 const GrGLVertexBuffer* vbuffer, | |
365 const GrGLIndexBuffer* i buffer); | |
366 | |
352 private: | 367 private: |
368 GrGLuint fBoundVertexArrayID; | |
353 GrGLuint fBoundVertexBufferID; | 369 GrGLuint fBoundVertexBufferID; |
354 GrGLuint fBoundIndexBufferID; | 370 bool fBoundVertexArrayIDIsValid; |
355 bool fBoundVertexBufferIDIsValid; | 371 bool fBoundVertexBufferIDIsValid; |
356 bool fBoundIndexBufferIDIsValid; | |
357 | 372 |
358 struct AttribArray { | 373 GrGLuint fDefaultVertexArrayBoundIndexBufferID; |
359 public: | 374 bool fDefaultVertexArrayBoundIndexBufferIDIsValid; |
360 void set(const GrGpuGL* gpu, | 375 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 |
361 HWGeometryState* geoState, | 376 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of |
362 int index, | 377 // GrGpuGL. |
363 GrGLVertexBuffer* vertexBuffer, | 378 GrGLAttribArrayState fDefaultVertexArrayAttribState; |
364 GrGLint size, | |
365 GrGLenum type, | |
366 GrGLboolean normalized, | |
367 GrGLsizei stride, | |
368 GrGLvoid* offset); | |
369 | 379 |
370 void disable(const GrGpuGL* gpu, int index) { | 380 // This is used when we're using a core profile and the vertices are in a VBO. |
371 if (!fEnableIsValid || fEnabled) { | 381 GrGLVertexArray* fVBOVertexArray; |
372 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(inde x)); | |
373 fEnableIsValid = true; | |
374 fEnabled = false; | |
375 } | |
376 } | |
377 | |
378 void invalidate() { | |
379 fEnableIsValid = false; | |
380 fAttribPointerIsValid = false; | |
381 } | |
382 | |
383 bool isVertexBufferIDBound(GrGLuint id) const { | |
384 return fAttribPointerIsValid && id == fVertexBufferID; | |
385 } | |
386 private: | |
387 bool fEnableIsValid; | |
388 bool fAttribPointerIsValid; | |
389 bool fEnabled; | |
390 GrGLuint fVertexBufferID; | |
391 GrGLint fSize; | |
392 GrGLenum fType; | |
393 GrGLboolean fNormalized; | |
394 GrGLsizei fStride; | |
395 GrGLvoid* fOffset; | |
396 }; | |
397 SkAutoTArray<AttribArray> fAttribArrays; | |
398 int fAttribArrayCount; | |
399 } fHWGeometryState; | 382 } fHWGeometryState; |
400 | 383 |
401 struct { | 384 struct { |
402 GrBlendCoeff fSrcCoeff; | 385 GrBlendCoeff fSrcCoeff; |
403 GrBlendCoeff fDstCoeff; | 386 GrBlendCoeff fDstCoeff; |
404 GrColor fConstColor; | 387 GrColor fConstColor; |
405 bool fConstColorValid; | 388 bool fConstColorValid; |
406 TriState fEnabled; | 389 TriState fEnabled; |
407 | 390 |
408 void invalidate() { | 391 void invalidate() { |
(...skipping 29 matching lines...) Expand all Loading... | |
438 // we record what stencil format worked last time to hopefully exit early | 421 // we record what stencil format worked last time to hopefully exit early |
439 // from our loop that tries stencil formats and calls check fb status. | 422 // from our loop that tries stencil formats and calls check fb status. |
440 int fLastSuccessfulStencilFmtIdx; | 423 int fLastSuccessfulStencilFmtIdx; |
441 | 424 |
442 bool fPrintedCaps; | 425 bool fPrintedCaps; |
443 | 426 |
444 typedef GrGpu INHERITED; | 427 typedef GrGpu INHERITED; |
445 }; | 428 }; |
446 | 429 |
447 #endif | 430 #endif |
OLD | NEW |