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 "GrBinHashKey.h"
12 #include "GrDrawState.h"
13 #include "GrGLContext.h"
14 #include "GrGLIRect.h"
15 #include "GrGLIndexBuffer.h"
16 #include "GrGLProgram.h"
17 #include "GrGLStencilBuffer.h"
18 #include "GrGLTexture.h"
19 #include "GrGLVertexArray.h"
20 #include "GrGLVertexBuffer.h"
22 #include "GrTHashTable.h"
26 #define PROGRAM_CACHE_STATS
29 class GrGpuGL : public GrGpu {
31 GrGpuGL(const GrGLContext& ctx, GrContext* context);
34 const GrGLContext& glContext() const { return fGLContext; }
36 const GrGLInterface* glInterface() const { return fGLContext.interface(); }
37 const GrGLContextInfo& ctxInfo() const { return fGLContext; }
38 GrGLStandard glStandard() const { return fGLContext.standard(); }
39 GrGLVersion glVersion() const { return fGLContext.version(); }
40 GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
41 const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
43 // Used by GrGLProgram and GrGLTexGenProgramEffects to configure OpenGL state.
44 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
45 void setProjectionMatrix(const SkMatrix& matrix,
46 const SkISize& renderTargetSize,
47 GrSurfaceOrigin renderTargetOrigin);
48 enum TexGenComponents {
49 kS_TexGenComponents = 1,
50 kST_TexGenComponents = 2,
51 kSTR_TexGenComponents = 3
53 void enableTexGen(int unitIdx, TexGenComponents, const GrGLfloat* coefficients);
54 void enableTexGen(int unitIdx, TexGenComponents, const SkMatrix& matrix);
55 void flushTexGenSettings(int numUsedTexCoordSets);
56 bool shouldUseFixedFunctionTexturing() const {
57 return this->glCaps().fixedFunctionSupport() &&
58 this->glCaps().pathRenderingSupport();
61 bool programUnitTest(int maxStages);
64 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
65 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
66 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
67 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
68 virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE;
69 virtual bool readPixelsWillPayForYFlip(
70 GrRenderTarget* renderTarget,
72 int width, int height,
74 size_t rowBytes) const SK_OVERRIDE;
75 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
77 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
79 virtual void abandonResources() SK_OVERRIDE;
81 // These functions should be used to bind GL objects. They track the GL state and skip redundant
82 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
83 void bindVertexArray(GrGLuint id) {
84 fHWGeometryState.setVertexArrayID(this, id);
86 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
87 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
89 void bindVertexBuffer(GrGLuint id) {
90 fHWGeometryState.setVertexBufferID(this, id);
93 // These callbacks update state tracking when GL objects are deleted. They are called from
94 // GrGLResource onRelease functions.
95 void notifyVertexArrayDelete(GrGLuint id) {
96 fHWGeometryState.notifyVertexArrayDelete(id);
98 void notifyVertexBufferDelete(GrGLuint id) {
99 fHWGeometryState.notifyVertexBufferDelete(id);
101 void notifyIndexBufferDelete(GrGLuint id) {
102 fHWGeometryState.notifyIndexBufferDelete(id);
104 void notifyTextureDelete(GrGLTexture* texture);
105 void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
108 virtual bool onCopySurface(GrSurface* dst,
110 const SkIRect& srcRect,
111 const SkIPoint& dstPoint) SK_OVERRIDE;
113 virtual bool onCanCopySurface(GrSurface* dst,
115 const SkIRect& srcRect,
116 const SkIPoint& dstPoint) SK_OVERRIDE;
120 virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
122 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
124 size_t rowBytes) SK_OVERRIDE;
125 virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
126 virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
127 virtual GrPath* onCreatePath(const SkPath&, const SkStrokeRec&) 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 onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE;
139 virtual void onForceRenderTargetFlush() SK_OVERRIDE;
141 virtual bool onReadPixels(GrRenderTarget* target,
143 int width, int height,
146 size_t rowBytes) SK_OVERRIDE;
148 virtual bool onWriteTexturePixels(GrTexture* texture,
149 int left, int top, int width, int height,
150 GrPixelConfig config, const void* buffer,
151 size_t rowBytes) SK_OVERRIDE;
153 virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
155 virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
157 virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
158 virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
160 virtual void clearStencil() SK_OVERRIDE;
161 virtual void clearStencilClip(const SkIRect& rect,
162 bool insideClip) SK_OVERRIDE;
163 virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
165 // binds texture unit in GL
166 void setTextureUnit(int unitIdx);
168 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
169 // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
170 // index is relative to the returned offset.
171 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
173 // Subclasses should call this to flush the blend state.
174 // The params should be the final coefficients to apply
175 // (after any blending optimizations or dual source blending considerations
176 // have been accounted for).
177 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
179 bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
181 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
183 class ProgramCache : public ::SkNoncopyable {
185 ProgramCache(GrGpuGL* gpu);
189 GrGLProgram* getProgram(const GrGLProgramDesc& desc,
190 const GrEffectStage* colorStages[],
191 const GrEffectStage* coverageStages[]);
195 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
196 // shader before evicting from the cache.
205 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
206 // of the index of where it should be inserted.
207 int search(const GrGLProgramDesc& desc) const;
209 // sorted array of all the entries
210 Entry* fEntries[kMaxEntries];
211 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
212 // searching fEntries.
213 Entry* fHashTable[1 << kHashBits];
216 unsigned int fCurrLRUStamp;
218 #ifdef PROGRAM_CACHE_STATS
221 int fHashMisses; // cache hit but hash table missed
225 // flushes dithering, color-mask, and face culling stat
226 void flushMiscFixedFunctionState();
228 // flushes the scissor. see the note on flushBoundTextureAndParams about
229 // flushing the scissor after that function is called.
232 void initFSAASupport();
234 // determines valid stencil formats
235 void initStencilFormats();
237 // sets a texture unit to use for texture operations other than binding a texture to a program.
238 // ensures that such operations don't negatively interact with tracking bound textures.
239 void setScratchTextureUnit();
241 // bound is region that may be modified and therefore has to be resolved.
242 // NULL means whole target. Can be an empty rect.
243 void flushRenderTarget(const SkIRect* bound);
244 void flushStencil(DrawType);
245 void flushAAState(DrawType);
246 void flushPathStencilSettings(SkPath::FillType fill);
248 bool configToGLFormats(GrPixelConfig config,
249 bool getSizedInternal,
250 GrGLenum* internalFormat,
251 GrGLenum* externalFormat,
252 GrGLenum* externalType);
253 // helper for onCreateTexture and writeTexturePixels
254 bool uploadTexData(const GrGLTexture::Desc& desc,
256 int left, int top, int width, int height,
257 GrPixelConfig dataConfig,
261 bool createRenderTargetObjects(int width, int height,
263 GrGLRenderTarget::Desc* desc);
265 GrGLContext fGLContext;
267 // GL program-related state
268 ProgramCache* fProgramCache;
269 SkAutoTUnref<GrGLProgram> fCurrentProgram;
271 ///////////////////////////////////////////////////////////////////////////
272 ///@name Caching of GL State
274 int fHWActiveTextureUnitIdx;
275 GrGLuint fHWProgramID;
277 GrGLProgram::SharedGLState fSharedGLProgramState;
285 // last scissor / viewport scissor state seen by the GL.
290 fEnabled = kUnknown_TriState;
293 } fHWScissorSettings;
295 GrGLIRect fHWViewport;
298 * Tracks bound vertex and index buffers and vertex attrib array state.
300 class HWGeometryState {
302 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
304 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
307 fBoundVertexArrayIDIsValid = false;
308 fBoundVertexBufferIDIsValid = false;
309 fDefaultVertexArrayBoundIndexBufferID = false;
310 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
311 fDefaultVertexArrayAttribState.invalidate();
312 if (NULL != fVBOVertexArray) {
313 fVBOVertexArray->invalidateCachedState();
317 void notifyVertexArrayDelete(GrGLuint id) {
318 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
319 // Does implicit bind to 0
320 fBoundVertexArrayID = 0;
324 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
325 if (!gpu->glCaps().vertexArrayObjectSupport()) {
326 SkASSERT(0 == arrayID);
329 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
330 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
331 fBoundVertexArrayIDIsValid = true;
332 fBoundVertexArrayID = arrayID;
336 void notifyVertexBufferDelete(GrGLuint id) {
337 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
338 fBoundVertexBufferID = 0;
340 if (NULL != fVBOVertexArray) {
341 fVBOVertexArray->notifyVertexBufferDelete(id);
343 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
346 void notifyIndexBufferDelete(GrGLuint id) {
347 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
348 id == fDefaultVertexArrayBoundIndexBufferID) {
349 fDefaultVertexArrayBoundIndexBufferID = 0;
351 if (NULL != fVBOVertexArray) {
352 fVBOVertexArray->notifyIndexBufferDelete(id);
356 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
357 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
358 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
359 fBoundVertexBufferIDIsValid = true;
360 fBoundVertexBufferID = id;
365 * Binds the default vertex array and binds the index buffer. This is used when binding
366 * an index buffer in order to update it.
368 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
369 this->setVertexArrayID(gpu, 0);
370 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
371 id != fDefaultVertexArrayBoundIndexBufferID) {
372 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
373 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
374 fDefaultVertexArrayBoundIndexBufferID = id;
379 * Binds the vertex array object that should be used to render from the vertex buffer.
380 * The vertex array is bound and its attrib array state object is returned. The vertex
381 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
382 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
384 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
385 const GrGLVertexBuffer* vbuffer,
386 const GrGLIndexBuffer* ibuffer);
389 GrGLuint fBoundVertexArrayID;
390 GrGLuint fBoundVertexBufferID;
391 bool fBoundVertexArrayIDIsValid;
392 bool fBoundVertexBufferIDIsValid;
394 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
395 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
396 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
397 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
399 GrGLAttribArrayState fDefaultVertexArrayAttribState;
401 // This is used when we're using a core profile and the vertices are in a VBO.
402 GrGLVertexArray* fVBOVertexArray;
406 GrBlendCoeff fSrcCoeff;
407 GrBlendCoeff fDstCoeff;
409 bool fConstColorValid;
413 fSrcCoeff = kInvalid_GrBlendCoeff;
414 fDstCoeff = kInvalid_GrBlendCoeff;
415 fConstColorValid = false;
416 fEnabled = kUnknown_TriState;
421 TriState fMSAAEnabled;
422 TriState fSmoothLineEnabled;
424 fMSAAEnabled = kUnknown_TriState;
425 fSmoothLineEnabled = kUnknown_TriState;
430 GrGLProgram::MatrixState fHWProjectionMatrixState;
432 GrStencilSettings fHWStencilSettings;
433 TriState fHWStencilTestEnabled;
434 GrStencilSettings fHWPathStencilSettings;
436 GrDrawState::DrawFace fHWDrawFace;
437 TriState fHWWriteToColor;
438 TriState fHWDitherEnabled;
439 GrRenderTarget* fHWBoundRenderTarget;
440 SkTArray<GrTexture*, true> fHWBoundTextures;
444 GrGLint fNumComponents;
445 GrGLfloat fCoefficients[3 * 3];
447 int fHWActiveTexGenSets;
448 SkTArray<TexGenData, true> fHWTexGenSettings;
451 // we record what stencil format worked last time to hopefully exit early
452 // from our loop that tries stencil formats and calls check fb status.
453 int fLastSuccessfulStencilFmtIdx;
455 typedef GrGpu INHERITED;