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 virtual void discard(GrRenderTarget*) SK_OVERRIDE;
45 // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
47 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
48 void setProjectionMatrix(const SkMatrix& matrix,
49 const SkISize& renderTargetSize,
50 GrSurfaceOrigin renderTargetOrigin);
51 enum PathTexGenComponents {
52 kS_PathTexGenComponents = 1,
53 kST_PathTexGenComponents = 2,
54 kSTR_PathTexGenComponents = 3
56 void enablePathTexGen(int unitIdx, PathTexGenComponents, const GrGLfloat* coefficients);
57 void enablePathTexGen(int unitIdx, PathTexGenComponents, const SkMatrix& matrix);
58 void flushPathTexGenSettings(int numUsedTexCoordSets);
59 bool shouldUseFixedFunctionTexturing() const {
60 return this->glCaps().pathRenderingSupport();
63 bool programUnitTest(int maxStages);
66 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
67 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
68 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
69 GrPixelConfig surfaceConfig) const SK_OVERRIDE;
70 virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE;
71 virtual bool readPixelsWillPayForYFlip(
72 GrRenderTarget* renderTarget,
74 int width, int height,
76 size_t rowBytes) const SK_OVERRIDE;
77 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
79 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
81 virtual void abandonResources() SK_OVERRIDE;
83 // These functions should be used to bind GL objects. They track the GL state and skip redundant
84 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
85 void bindVertexArray(GrGLuint id) {
86 fHWGeometryState.setVertexArrayID(this, id);
88 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
89 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
91 void bindVertexBuffer(GrGLuint id) {
92 fHWGeometryState.setVertexBufferID(this, id);
95 // These callbacks update state tracking when GL objects are deleted. They are called from
96 // GrGLResource onRelease functions.
97 void notifyVertexArrayDelete(GrGLuint id) {
98 fHWGeometryState.notifyVertexArrayDelete(id);
100 void notifyVertexBufferDelete(GrGLuint id) {
101 fHWGeometryState.notifyVertexBufferDelete(id);
103 void notifyIndexBufferDelete(GrGLuint id) {
104 fHWGeometryState.notifyIndexBufferDelete(id);
106 void notifyTextureDelete(GrGLTexture* texture);
107 void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
110 virtual bool onCopySurface(GrSurface* dst,
112 const SkIRect& srcRect,
113 const SkIPoint& dstPoint) SK_OVERRIDE;
115 virtual bool onCanCopySurface(GrSurface* dst,
117 const SkIRect& srcRect,
118 const SkIPoint& dstPoint) SK_OVERRIDE;
122 virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
124 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
126 size_t rowBytes) SK_OVERRIDE;
127 virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
128 virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
129 virtual GrPath* onCreatePath(const SkPath&, const SkStrokeRec&) SK_OVERRIDE;
130 virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
131 virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
132 virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
134 int height) SK_OVERRIDE;
135 virtual bool attachStencilBufferToRenderTarget(
137 GrRenderTarget* rt) SK_OVERRIDE;
139 virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) 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;
159 virtual void onGpuDrawPaths(int, const GrPath**, const SkMatrix*,
161 SkStrokeRec::Style) SK_OVERRIDE;
163 virtual void clearStencil() SK_OVERRIDE;
164 virtual void clearStencilClip(const SkIRect& rect,
165 bool insideClip) SK_OVERRIDE;
166 virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
168 // GrDrawTarget ovverides
169 virtual void didAddGpuTraceMarker() SK_OVERRIDE;
170 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
172 // binds texture unit in GL
173 void setTextureUnit(int unitIdx);
175 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
176 // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
177 // index is relative to the returned offset.
178 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
180 // Subclasses should call this to flush the blend state.
181 // The params should be the final coefficients to apply
182 // (after any blending optimizations or dual source blending considerations
183 // have been accounted for).
184 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
186 bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
188 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
190 class ProgramCache : public ::SkNoncopyable {
192 ProgramCache(GrGpuGL* gpu);
196 GrGLProgram* getProgram(const GrGLProgramDesc& desc,
197 const GrEffectStage* colorStages[],
198 const GrEffectStage* coverageStages[]);
202 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
203 // shader before evicting from the cache.
212 // binary search for entry matching desc. returns index into fEntries that matches desc or ~
213 // of the index of where it should be inserted.
214 int search(const GrGLProgramDesc& desc) const;
216 // sorted array of all the entries
217 Entry* fEntries[kMaxEntries];
218 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
219 // searching fEntries.
220 Entry* fHashTable[1 << kHashBits];
223 unsigned int fCurrLRUStamp;
225 #ifdef PROGRAM_CACHE_STATS
228 int fHashMisses; // cache hit but hash table missed
232 // flushes dithering, color-mask, and face culling stat
233 void flushMiscFixedFunctionState();
235 // flushes the scissor. see the note on flushBoundTextureAndParams about
236 // flushing the scissor after that function is called.
239 void initFSAASupport();
241 // determines valid stencil formats
242 void initStencilFormats();
244 // sets a texture unit to use for texture operations other than binding a texture to a program.
245 // ensures that such operations don't negatively interact with tracking bound textures.
246 void setScratchTextureUnit();
248 // bound is region that may be modified and therefore has to be resolved.
249 // NULL means whole target. Can be an empty rect.
250 void flushRenderTarget(const SkIRect* bound);
251 void flushStencil(DrawType);
252 void flushAAState(DrawType);
253 void flushPathStencilSettings(SkPath::FillType fill);
255 bool configToGLFormats(GrPixelConfig config,
256 bool getSizedInternal,
257 GrGLenum* internalFormat,
258 GrGLenum* externalFormat,
259 GrGLenum* externalType);
260 // helper for onCreateTexture and writeTexturePixels
261 bool uploadTexData(const GrGLTexture::Desc& desc,
263 int left, int top, int width, int height,
264 GrPixelConfig dataConfig,
268 bool createRenderTargetObjects(int width, int height,
270 GrGLRenderTarget::Desc* desc);
272 GrGLContext fGLContext;
274 // GL program-related state
275 ProgramCache* fProgramCache;
276 SkAutoTUnref<GrGLProgram> fCurrentProgram;
278 ///////////////////////////////////////////////////////////////////////////
279 ///@name Caching of GL State
281 int fHWActiveTextureUnitIdx;
282 GrGLuint fHWProgramID;
284 GrGLProgram::SharedGLState fSharedGLProgramState;
292 // last scissor / viewport scissor state seen by the GL.
297 fEnabled = kUnknown_TriState;
300 } fHWScissorSettings;
302 GrGLIRect fHWViewport;
305 * Tracks bound vertex and index buffers and vertex attrib array state.
307 class HWGeometryState {
309 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
311 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
314 fBoundVertexArrayIDIsValid = false;
315 fBoundVertexBufferIDIsValid = false;
316 fDefaultVertexArrayBoundIndexBufferID = false;
317 fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
318 fDefaultVertexArrayAttribState.invalidate();
319 if (NULL != fVBOVertexArray) {
320 fVBOVertexArray->invalidateCachedState();
324 void notifyVertexArrayDelete(GrGLuint id) {
325 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
326 // Does implicit bind to 0
327 fBoundVertexArrayID = 0;
331 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
332 if (!gpu->glCaps().vertexArrayObjectSupport()) {
333 SkASSERT(0 == arrayID);
336 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
337 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
338 fBoundVertexArrayIDIsValid = true;
339 fBoundVertexArrayID = arrayID;
343 void notifyVertexBufferDelete(GrGLuint id) {
344 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
345 fBoundVertexBufferID = 0;
347 if (NULL != fVBOVertexArray) {
348 fVBOVertexArray->notifyVertexBufferDelete(id);
350 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
353 void notifyIndexBufferDelete(GrGLuint id) {
354 if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
355 id == fDefaultVertexArrayBoundIndexBufferID) {
356 fDefaultVertexArrayBoundIndexBufferID = 0;
358 if (NULL != fVBOVertexArray) {
359 fVBOVertexArray->notifyIndexBufferDelete(id);
363 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
364 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
365 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
366 fBoundVertexBufferIDIsValid = true;
367 fBoundVertexBufferID = id;
372 * Binds the default vertex array and binds the index buffer. This is used when binding
373 * an index buffer in order to update it.
375 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
376 this->setVertexArrayID(gpu, 0);
377 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
378 id != fDefaultVertexArrayBoundIndexBufferID) {
379 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
380 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
381 fDefaultVertexArrayBoundIndexBufferID = id;
386 * Binds the vertex array object that should be used to render from the vertex buffer.
387 * The vertex array is bound and its attrib array state object is returned. The vertex
388 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
389 * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
391 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
392 const GrGLVertexBuffer* vbuffer,
393 const GrGLIndexBuffer* ibuffer);
396 GrGLuint fBoundVertexArrayID;
397 GrGLuint fBoundVertexBufferID;
398 bool fBoundVertexArrayIDIsValid;
399 bool fBoundVertexBufferIDIsValid;
401 GrGLuint fDefaultVertexArrayBoundIndexBufferID;
402 bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
403 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
404 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
406 GrGLAttribArrayState fDefaultVertexArrayAttribState;
408 // This is used when we're using a core profile and the vertices are in a VBO.
409 GrGLVertexArray* fVBOVertexArray;
413 GrBlendCoeff fSrcCoeff;
414 GrBlendCoeff fDstCoeff;
416 bool fConstColorValid;
420 fSrcCoeff = kInvalid_GrBlendCoeff;
421 fDstCoeff = kInvalid_GrBlendCoeff;
422 fConstColorValid = false;
423 fEnabled = kUnknown_TriState;
428 TriState fMSAAEnabled;
429 TriState fSmoothLineEnabled;
431 fMSAAEnabled = kUnknown_TriState;
432 fSmoothLineEnabled = kUnknown_TriState;
437 GrGLProgram::MatrixState fHWProjectionMatrixState;
439 GrStencilSettings fHWStencilSettings;
440 TriState fHWStencilTestEnabled;
441 GrStencilSettings fHWPathStencilSettings;
443 GrDrawState::DrawFace fHWDrawFace;
444 TriState fHWWriteToColor;
445 TriState fHWDitherEnabled;
446 GrRenderTarget* fHWBoundRenderTarget;
447 SkTArray<GrTexture*, true> fHWBoundTextures;
449 struct PathTexGenData {
451 GrGLint fNumComponents;
452 GrGLfloat fCoefficients[3 * 3];
454 int fHWActivePathTexGenSets;
455 SkTArray<PathTexGenData, true> fHWPathTexGenSettings;
458 // we record what stencil format worked last time to hopefully exit early
459 // from our loop that tries stencil formats and calls check fb status.
460 int fLastSuccessfulStencilFmtIdx;
462 typedef GrGpu INHERITED;