2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrGpuGL_DEFINED
9 #define GrGpuGL_DEFINED
11 #include "GrDrawState.h"
12 #include "GrGLContext.h"
13 #include "GrGLIRect.h"
14 #include "GrGLIndexBuffer.h"
15 #include "GrGLPathRendering.h"
16 #include "GrGLProgram.h"
17 #include "GrGLRenderTarget.h"
18 #include "GrGLStencilBuffer.h"
19 #include "GrGLTexture.h"
20 #include "GrGLVertexArray.h"
21 #include "GrGLVertexBuffer.h"
23 #include "GrOptDrawState.h"
27 #define PROGRAM_CACHE_STATS
30 class GrGpuGL : public GrGpu {
32 GrGpuGL(const GrGLContext& ctx, GrContext* context);
35 virtual void contextAbandoned() SK_OVERRIDE;
37 const GrGLContext& glContext() const { return fGLContext; }
39 const GrGLInterface* glInterface() const { return fGLContext.interface(); }
40 const GrGLContextInfo& ctxInfo() const { return fGLContext; }
41 GrGLStandard glStandard() const { return fGLContext.standard(); }
42 GrGLVersion glVersion() const { return fGLContext.version(); }
43 GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
44 const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
46 GrGLPathRendering* glPathRendering() {
47 SkASSERT(glCaps().pathRenderingSupport());
48 return static_cast<GrGLPathRendering*>(pathRendering());
51 virtual void discard(GrRenderTarget*) SK_OVERRIDE;
53 // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
55 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
57 bool programUnitTest(int maxStages);
60 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
61 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
62 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
63 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
64 virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE;
65 virtual bool readPixelsWillPayForYFlip(
66 GrRenderTarget* renderTarget,
68 int width, int height,
70 size_t rowBytes) const SK_OVERRIDE;
71 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
73 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) SK_OVERRIDE;
75 // These functions should be used to bind GL objects. They track the GL state and skip redundant
76 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
77 void bindVertexArray(GrGLuint id) {
78 fHWGeometryState.setVertexArrayID(this, id);
80 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
81 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
83 void bindVertexBuffer(GrGLuint id) {
84 fHWGeometryState.setVertexBufferID(this, id);
87 // These callbacks update state tracking when GL objects are deleted. They are called from
88 // GrGLResource onRelease functions.
89 void notifyVertexArrayDelete(GrGLuint id) {
90 fHWGeometryState.notifyVertexArrayDelete(id);
92 void notifyVertexBufferDelete(GrGLuint id) {
93 fHWGeometryState.notifyVertexBufferDelete(id);
95 void notifyIndexBufferDelete(GrGLuint id) {
96 fHWGeometryState.notifyIndexBufferDelete(id);
99 // DrawTarget overrides
100 virtual bool copySurface(GrSurface* dst,
102 const SkIRect& srcRect,
103 const SkIPoint& dstPoint) SK_OVERRIDE;
105 virtual bool canCopySurface(GrSurface* dst,
107 const SkIRect& srcRect,
108 const SkIPoint& dstPoint) SK_OVERRIDE;
111 virtual void buildProgramDesc(const GrOptDrawState&,
112 const GrProgramDesc::DescInfo&,
114 const GrDeviceCoordTexture* dstCopy,
115 GrProgramDesc*) SK_OVERRIDE;
119 virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
121 virtual GrTexture* onCreateTexture(const GrSurfaceDesc& desc,
123 size_t rowBytes) SK_OVERRIDE;
124 virtual GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
125 const void* srcData) SK_OVERRIDE;
126 virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
127 virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
128 virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
129 virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
130 virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
132 int height) SK_OVERRIDE;
133 virtual bool attachStencilBufferToRenderTarget(
135 GrRenderTarget* rt) SK_OVERRIDE;
137 virtual void onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
138 bool canIgnoreRect) SK_OVERRIDE;
140 virtual void onClearStencilClip(GrRenderTarget*,
142 bool insideClip) SK_OVERRIDE;
144 virtual bool onReadPixels(GrRenderTarget* target,
146 int width, int height,
149 size_t rowBytes) SK_OVERRIDE;
151 virtual bool onWriteTexturePixels(GrTexture* texture,
152 int left, int top, int width, int height,
153 GrPixelConfig config, const void* buffer,
154 size_t rowBytes) SK_OVERRIDE;
156 virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
158 virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
161 virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
162 virtual bool flushGraphicsState(DrawType,
163 const GrClipMaskManager::ScissorState&,
164 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
166 // GrDrawTarget overrides
167 virtual void didAddGpuTraceMarker() SK_OVERRIDE;
168 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
170 // binds texture unit in GL
171 void setTextureUnit(int unitIdx);
173 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
174 // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
175 // index is relative to the returned offset.
176 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
178 // Subclasses should call this to flush the blend state.
179 // The params should be the final coefficients to apply
180 // (after any blending optimizations or dual source blending considerations
181 // have been accounted for).
182 void flushBlend(const GrOptDrawState& optState, bool isLines,
183 GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
185 bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
187 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
189 class ProgramCache : public ::SkNoncopyable {
191 ProgramCache(GrGpuGL* gpu);
195 GrGLProgram* getProgram(const GrOptDrawState&, DrawType);
199 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
200 // shader before evicting from the cache.
209 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
210 // of the index of where it should be inserted.
211 int search(const GrProgramDesc& desc) const;
213 // sorted array of all the entries
214 Entry* fEntries[kMaxEntries];
215 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
216 // searching fEntries.
217 Entry* fHashTable[1 << kHashBits];
220 unsigned int fCurrLRUStamp;
222 #ifdef PROGRAM_CACHE_STATS
225 int fHashMisses; // cache hit but hash table missed
229 // flushes dithering, color-mask, and face culling stat
230 void flushMiscFixedFunctionState(const GrOptDrawState&);
232 // flushes the scissor. see the note on flushBoundTextureAndParams about
233 // flushing the scissor after that function is called.
234 void flushScissor(const GrClipMaskManager::ScissorState&,
235 const GrGLIRect& rtViewport,
236 GrSurfaceOrigin rtOrigin);
238 // disables the scissor
239 void disableScissor();
241 void initFSAASupport();
243 // determines valid stencil formats
244 void initStencilFormats();
246 // sets a texture unit to use for texture operations other than binding a texture to a program.
247 // ensures that such operations don't negatively interact with tracking bound textures.
248 void setScratchTextureUnit();
250 // bounds is region that may be modified and therefore has to be resolved.
251 // NULL means whole target. Can be an empty rect.
252 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
254 void flushStencil(const GrStencilSettings&, DrawType);
255 void flushAAState(const GrOptDrawState&, DrawType);
257 bool configToGLFormats(GrPixelConfig config,
258 bool getSizedInternal,
259 GrGLenum* internalFormat,
260 GrGLenum* externalFormat,
261 GrGLenum* externalType);
262 // helper for onCreateTexture and writeTexturePixels
263 bool uploadTexData(const GrSurfaceDesc& desc,
265 int left, int top, int width, int height,
266 GrPixelConfig dataConfig,
270 // helper for onCreateCompressedTexture. If width and height are
271 // set to -1, then this function will use desc.fWidth and desc.fHeight
272 // for the size of the data. The isNewTexture flag should be set to true
273 // whenever a new texture needs to be created. Otherwise, we assume that
274 // the texture is already in GPU memory and that it's going to be updated
276 bool uploadCompressedTexData(const GrSurfaceDesc& desc,
278 bool isNewTexture = true,
279 int left = 0, int top = 0,
280 int width = -1, int height = -1);
282 bool createRenderTargetObjects(const GrSurfaceDesc&, GrGLuint texID, GrGLRenderTarget::IDDesc*);
284 GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
286 GrGLContext fGLContext;
288 // GL program-related state
289 ProgramCache* fProgramCache;
290 SkAutoTUnref<GrGLProgram> fCurrentProgram;
292 ///////////////////////////////////////////////////////////////////////////
293 ///@name Caching of GL State
295 int fHWActiveTextureUnitIdx;
296 GrGLuint fHWProgramID;
304 // last scissor / viewport scissor state seen by the GL.
309 fEnabled = kUnknown_TriState;
312 } fHWScissorSettings;
314 GrGLIRect fHWViewport;
317 * Tracks bound vertex and index buffers and vertex attrib array state.
319 class HWGeometryState {
321 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
323 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
326 fBoundVertexArrayIDIsValid = false;
327 fBoundVertexBufferIDIsValid = false;
328 fDefaultVertexArrayBoundIndexBufferID = false;
329 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
330 fDefaultVertexArrayAttribState.invalidate();
331 if (fVBOVertexArray) {
332 fVBOVertexArray->invalidateCachedState();
336 void notifyVertexArrayDelete(GrGLuint id) {
337 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
338 // Does implicit bind to 0
339 fBoundVertexArrayID = 0;
343 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
344 if (!gpu->glCaps().vertexArrayObjectSupport()) {
345 SkASSERT(0 == arrayID);
348 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
349 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
350 fBoundVertexArrayIDIsValid = true;
351 fBoundVertexArrayID = arrayID;
355 void notifyVertexBufferDelete(GrGLuint id) {
356 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
357 fBoundVertexBufferID = 0;
359 if (fVBOVertexArray) {
360 fVBOVertexArray->notifyVertexBufferDelete(id);
362 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
365 void notifyIndexBufferDelete(GrGLuint id) {
366 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
367 id == fDefaultVertexArrayBoundIndexBufferID) {
368 fDefaultVertexArrayBoundIndexBufferID = 0;
370 if (fVBOVertexArray) {
371 fVBOVertexArray->notifyIndexBufferDelete(id);
375 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
376 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
377 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
378 fBoundVertexBufferIDIsValid = true;
379 fBoundVertexBufferID = id;
384 * Binds the default vertex array and binds the index buffer. This is used when binding
385 * an index buffer in order to update it.
387 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
388 this->setVertexArrayID(gpu, 0);
389 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
390 id != fDefaultVertexArrayBoundIndexBufferID) {
391 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
392 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
393 fDefaultVertexArrayBoundIndexBufferID = id;
398 * Binds the vertex array object that should be used to render from the vertex buffer.
399 * The vertex array is bound and its attrib array state object is returned. The vertex
400 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
401 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
403 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
404 const GrGLVertexBuffer* vbuffer,
405 const GrGLIndexBuffer* ibuffer);
408 GrGLuint fBoundVertexArrayID;
409 GrGLuint fBoundVertexBufferID;
410 bool fBoundVertexArrayIDIsValid;
411 bool fBoundVertexBufferIDIsValid;
413 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
414 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
415 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
416 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
418 GrGLAttribArrayState fDefaultVertexArrayAttribState;
420 // This is used when we're using a core profile and the vertices are in a VBO.
421 GrGLVertexArray* fVBOVertexArray;
425 GrBlendCoeff fSrcCoeff;
426 GrBlendCoeff fDstCoeff;
428 bool fConstColorValid;
432 fSrcCoeff = kInvalid_GrBlendCoeff;
433 fDstCoeff = kInvalid_GrBlendCoeff;
434 fConstColorValid = false;
435 fEnabled = kUnknown_TriState;
439 TriState fMSAAEnabled;
441 GrStencilSettings fHWStencilSettings;
442 TriState fHWStencilTestEnabled;
445 GrOptDrawState::DrawFace fHWDrawFace;
446 TriState fHWWriteToColor;
447 TriState fHWDitherEnabled;
448 uint32_t fHWBoundRenderTargetUniqueID;
449 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs;
453 // we record what stencil format worked last time to hopefully exit early
454 // from our loop that tries stencil formats and calls check fb status.
455 int fLastSuccessfulStencilFmtIdx;
457 typedef GrGpu INHERITED;
458 friend class GrGLPathRendering; // For accessing setTextureUnit.