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 "GrGLStencilBuffer.h"
18 #include "GrGLTexture.h"
19 #include "GrGLVertexArray.h"
20 #include "GrGLVertexBuffer.h"
25 #define PROGRAM_CACHE_STATS
28 class GrGpuGL : public GrGpu {
30 GrGpuGL(const GrGLContext& ctx, GrContext* context);
33 virtual void contextAbandoned() SK_OVERRIDE;
35 const GrGLContext& glContext() const { return fGLContext; }
37 const GrGLInterface* glInterface() const { return fGLContext.interface(); }
38 const GrGLContextInfo& ctxInfo() const { return fGLContext; }
39 GrGLStandard glStandard() const { return fGLContext.standard(); }
40 GrGLVersion glVersion() const { return fGLContext.version(); }
41 GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
42 const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
44 GrGLPathRendering* glPathRendering() {
45 SkASSERT(glCaps().pathRenderingSupport());
46 return static_cast<GrGLPathRendering*>(pathRendering());
49 virtual void discard(GrRenderTarget*) SK_OVERRIDE;
51 // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
53 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
55 bool programUnitTest(int maxStages);
58 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
59 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
60 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
61 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
62 virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE;
63 virtual bool readPixelsWillPayForYFlip(
64 GrRenderTarget* renderTarget,
66 int width, int height,
68 size_t rowBytes) const SK_OVERRIDE;
69 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
71 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
73 // These functions should be used to bind GL objects. They track the GL state and skip redundant
74 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
75 void bindVertexArray(GrGLuint id) {
76 fHWGeometryState.setVertexArrayID(this, id);
78 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
79 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
81 void bindVertexBuffer(GrGLuint id) {
82 fHWGeometryState.setVertexBufferID(this, id);
85 // These callbacks update state tracking when GL objects are deleted. They are called from
86 // GrGLResource onRelease functions.
87 void notifyVertexArrayDelete(GrGLuint id) {
88 fHWGeometryState.notifyVertexArrayDelete(id);
90 void notifyVertexBufferDelete(GrGLuint id) {
91 fHWGeometryState.notifyVertexBufferDelete(id);
93 void notifyIndexBufferDelete(GrGLuint id) {
94 fHWGeometryState.notifyIndexBufferDelete(id);
98 virtual bool onCopySurface(GrSurface* dst,
100 const SkIRect& srcRect,
101 const SkIPoint& dstPoint) SK_OVERRIDE;
103 virtual bool onCanCopySurface(GrSurface* dst,
105 const SkIRect& srcRect,
106 const SkIPoint& dstPoint) SK_OVERRIDE;
110 virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
112 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
114 size_t rowBytes) SK_OVERRIDE;
115 virtual GrTexture* onCreateCompressedTexture(const GrTextureDesc& desc,
116 const void* srcData) SK_OVERRIDE;
117 virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
118 virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
119 virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
120 virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
121 virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
123 int height) SK_OVERRIDE;
124 virtual bool attachStencilBufferToRenderTarget(
126 GrRenderTarget* rt) SK_OVERRIDE;
128 virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
129 bool canIgnoreRect) SK_OVERRIDE;
131 virtual bool onReadPixels(GrRenderTarget* target,
133 int width, int height,
136 size_t rowBytes) SK_OVERRIDE;
138 virtual bool onWriteTexturePixels(GrTexture* texture,
139 int left, int top, int width, int height,
140 GrPixelConfig config, const void* buffer,
141 size_t rowBytes) SK_OVERRIDE;
143 virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
145 virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
148 virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
149 virtual void clearStencilClip(GrRenderTarget*, const SkIRect& rect,
150 bool insideClip) SK_OVERRIDE;
151 virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
153 // GrDrawTarget overrides
154 virtual void didAddGpuTraceMarker() SK_OVERRIDE;
155 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
157 // binds texture unit in GL
158 void setTextureUnit(int unitIdx);
160 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
161 // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
162 // index is relative to the returned offset.
163 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
165 // Subclasses should call this to flush the blend state.
166 // The params should be the final coefficients to apply
167 // (after any blending optimizations or dual source blending considerations
168 // have been accounted for).
169 void flushBlend(const GrOptDrawState& optState, bool isLines,
170 GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
172 bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
174 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
176 class ProgramCache : public ::SkNoncopyable {
178 ProgramCache(GrGpuGL* gpu);
182 GrGLProgram* getProgram(const GrGLProgramDesc& desc,
183 const GrGeometryStage* geometryProcessor,
184 const GrFragmentStage* colorStages[],
185 const GrFragmentStage* coverageStages[]);
189 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
190 // shader before evicting from the cache.
199 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
200 // of the index of where it should be inserted.
201 int search(const GrGLProgramDesc& desc) const;
203 // sorted array of all the entries
204 Entry* fEntries[kMaxEntries];
205 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
206 // searching fEntries.
207 Entry* fHashTable[1 << kHashBits];
210 unsigned int fCurrLRUStamp;
212 #ifdef PROGRAM_CACHE_STATS
215 int fHashMisses; // cache hit but hash table missed
219 // flushes dithering, color-mask, and face culling stat
220 void flushMiscFixedFunctionState(const GrOptDrawState&);
222 // flushes the scissor. see the note on flushBoundTextureAndParams about
223 // flushing the scissor after that function is called.
224 void flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin);
226 void initFSAASupport();
228 // determines valid stencil formats
229 void initStencilFormats();
231 // sets a texture unit to use for texture operations other than binding a texture to a program.
232 // ensures that such operations don't negatively interact with tracking bound textures.
233 void setScratchTextureUnit();
235 // bounds is region that may be modified and therefore has to be resolved.
236 // NULL means whole target. Can be an empty rect.
237 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
239 void flushStencil(DrawType);
240 void flushAAState(const GrOptDrawState&, DrawType);
242 bool configToGLFormats(GrPixelConfig config,
243 bool getSizedInternal,
244 GrGLenum* internalFormat,
245 GrGLenum* externalFormat,
246 GrGLenum* externalType);
247 // helper for onCreateTexture and writeTexturePixels
248 bool uploadTexData(const GrGLTexture::Desc& desc,
250 int left, int top, int width, int height,
251 GrPixelConfig dataConfig,
255 // helper for onCreateCompressedTexture. If width and height are
256 // set to -1, then this function will use desc.fWidth and desc.fHeight
257 // for the size of the data. The isNewTexture flag should be set to true
258 // whenever a new texture needs to be created. Otherwise, we assume that
259 // the texture is already in GPU memory and that it's going to be updated
261 bool uploadCompressedTexData(const GrGLTexture::Desc& desc,
263 bool isNewTexture = true,
264 int left = 0, int top = 0,
265 int width = -1, int height = -1);
267 bool createRenderTargetObjects(int width, int height,
269 GrGLRenderTarget::Desc* desc);
271 GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
273 GrGLContext fGLContext;
275 // GL program-related state
276 ProgramCache* fProgramCache;
277 SkAutoTUnref<GrGLProgram> fCurrentProgram;
279 ///////////////////////////////////////////////////////////////////////////
280 ///@name Caching of GL State
282 int fHWActiveTextureUnitIdx;
283 GrGLuint fHWProgramID;
285 GrGLProgram::SharedGLState fSharedGLProgramState;
293 // last scissor / viewport scissor state seen by the GL.
298 fEnabled = kUnknown_TriState;
301 } fHWScissorSettings;
303 GrGLIRect fHWViewport;
306 * Tracks bound vertex and index buffers and vertex attrib array state.
308 class HWGeometryState {
310 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
312 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
315 fBoundVertexArrayIDIsValid = false;
316 fBoundVertexBufferIDIsValid = false;
317 fDefaultVertexArrayBoundIndexBufferID = false;
318 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
319 fDefaultVertexArrayAttribState.invalidate();
320 if (fVBOVertexArray) {
321 fVBOVertexArray->invalidateCachedState();
325 void notifyVertexArrayDelete(GrGLuint id) {
326 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
327 // Does implicit bind to 0
328 fBoundVertexArrayID = 0;
332 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
333 if (!gpu->glCaps().vertexArrayObjectSupport()) {
334 SkASSERT(0 == arrayID);
337 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
338 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
339 fBoundVertexArrayIDIsValid = true;
340 fBoundVertexArrayID = arrayID;
344 void notifyVertexBufferDelete(GrGLuint id) {
345 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
346 fBoundVertexBufferID = 0;
348 if (fVBOVertexArray) {
349 fVBOVertexArray->notifyVertexBufferDelete(id);
351 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
354 void notifyIndexBufferDelete(GrGLuint id) {
355 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
356 id == fDefaultVertexArrayBoundIndexBufferID) {
357 fDefaultVertexArrayBoundIndexBufferID = 0;
359 if (fVBOVertexArray) {
360 fVBOVertexArray->notifyIndexBufferDelete(id);
364 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
365 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
366 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
367 fBoundVertexBufferIDIsValid = true;
368 fBoundVertexBufferID = id;
373 * Binds the default vertex array and binds the index buffer. This is used when binding
374 * an index buffer in order to update it.
376 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
377 this->setVertexArrayID(gpu, 0);
378 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
379 id != fDefaultVertexArrayBoundIndexBufferID) {
380 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
381 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
382 fDefaultVertexArrayBoundIndexBufferID = id;
387 * Binds the vertex array object that should be used to render from the vertex buffer.
388 * The vertex array is bound and its attrib array state object is returned. The vertex
389 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
390 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
392 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
393 const GrGLVertexBuffer* vbuffer,
394 const GrGLIndexBuffer* ibuffer);
397 GrGLuint fBoundVertexArrayID;
398 GrGLuint fBoundVertexBufferID;
399 bool fBoundVertexArrayIDIsValid;
400 bool fBoundVertexBufferIDIsValid;
402 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
403 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
404 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
405 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
407 GrGLAttribArrayState fDefaultVertexArrayAttribState;
409 // This is used when we're using a core profile and the vertices are in a VBO.
410 GrGLVertexArray* fVBOVertexArray;
414 GrBlendCoeff fSrcCoeff;
415 GrBlendCoeff fDstCoeff;
417 bool fConstColorValid;
421 fSrcCoeff = kInvalid_GrBlendCoeff;
422 fDstCoeff = kInvalid_GrBlendCoeff;
423 fConstColorValid = false;
424 fEnabled = kUnknown_TriState;
428 TriState fMSAAEnabled;
430 GrStencilSettings fHWStencilSettings;
431 TriState fHWStencilTestEnabled;
434 GrDrawState::DrawFace fHWDrawFace;
435 TriState fHWWriteToColor;
436 TriState fHWDitherEnabled;
437 uint32_t fHWBoundRenderTargetUniqueID;
438 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs;
442 // we record what stencil format worked last time to hopefully exit early
443 // from our loop that tries stencil formats and calls check fb status.
444 int fLastSuccessfulStencilFmtIdx;
446 typedef GrGpu INHERITED;
447 friend class GrGLPathRendering; // For accessing setTextureUnit.