Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGpuGL.h
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #ifndef GrGpuGL_DEFINED
9 #define GrGpuGL_DEFINED
10
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"
21 #include "GrGpu.h"
22 #include "GrTHashTable.h"
23 #include "SkTypes.h"
24
25 #ifdef SK_DEVELOPER
26 #define PROGRAM_CACHE_STATS
27 #endif
28
29 class GrGpuGL : public GrGpu {
30 public:
31     GrGpuGL(const GrGLContext& ctx, GrContext* context);
32     virtual ~GrGpuGL();
33
34     const GrGLContext& glContext() const { return fGLContext; }
35
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(); }
42
43     virtual void discard(GrRenderTarget*) SK_OVERRIDE;
44
45     // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
46     // state.
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
55     };
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();
61     }
62
63     bool programUnitTest(int maxStages);
64
65     // GrGpu overrides
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,
73                                     int left, int top,
74                                     int width, int height,
75                                     GrPixelConfig config,
76                                     size_t rowBytes) const SK_OVERRIDE;
77     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
78
79     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
80
81     virtual void abandonResources() SK_OVERRIDE;
82
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);
87     }
88     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
89         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
90     }
91     void bindVertexBuffer(GrGLuint id) {
92         fHWGeometryState.setVertexBufferID(this, id);
93     }
94
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);
99     }
100     void notifyVertexBufferDelete(GrGLuint id) {
101         fHWGeometryState.notifyVertexBufferDelete(id);
102     }
103     void notifyIndexBufferDelete(GrGLuint id) {
104         fHWGeometryState.notifyIndexBufferDelete(id);
105     }
106     void notifyTextureDelete(GrGLTexture* texture);
107     void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
108
109 protected:
110     virtual bool onCopySurface(GrSurface* dst,
111                                GrSurface* src,
112                                const SkIRect& srcRect,
113                                const SkIPoint& dstPoint) SK_OVERRIDE;
114
115     virtual bool onCanCopySurface(GrSurface* dst,
116                                   GrSurface* src,
117                                   const SkIRect& srcRect,
118                                   const SkIPoint& dstPoint) SK_OVERRIDE;
119
120 private:
121     // GrGpu overrides
122     virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
123
124     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
125                                        const void* srcData,
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,
133                                                     int width,
134                                                     int height) SK_OVERRIDE;
135     virtual bool attachStencilBufferToRenderTarget(
136         GrStencilBuffer* sb,
137         GrRenderTarget* rt) SK_OVERRIDE;
138
139     virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE;
140
141     virtual bool onReadPixels(GrRenderTarget* target,
142                               int left, int top,
143                               int width, int height,
144                               GrPixelConfig,
145                               void* buffer,
146                               size_t rowBytes) SK_OVERRIDE;
147
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;
152
153     virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
154
155     virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
156
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*,
160                                 SkPath::FillType,
161                                 SkStrokeRec::Style) SK_OVERRIDE;
162
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;
167
168     // GrDrawTarget ovverides
169     virtual void didAddGpuTraceMarker() SK_OVERRIDE;
170     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
171
172     // binds texture unit in GL
173     void setTextureUnit(int unitIdx);
174
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);
179
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);
185
186     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
187
188     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
189
190     class ProgramCache : public ::SkNoncopyable {
191     public:
192         ProgramCache(GrGpuGL* gpu);
193         ~ProgramCache();
194
195         void abandon();
196         GrGLProgram* getProgram(const GrGLProgramDesc& desc,
197                                 const GrEffectStage* colorStages[],
198                                 const GrEffectStage* coverageStages[]);
199
200     private:
201         enum {
202             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
203             // shader before evicting from the cache.
204             kMaxEntries = 128,
205             kHashBits = 6,
206         };
207
208         struct Entry;
209
210         struct ProgDescLess;
211
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;
215
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];
221
222         int                         fCount;
223         unsigned int                fCurrLRUStamp;
224         GrGpuGL*                    fGpu;
225 #ifdef PROGRAM_CACHE_STATS
226         int                         fTotalRequests;
227         int                         fCacheMisses;
228         int                         fHashMisses; // cache hit but hash table missed
229 #endif
230     };
231
232     // flushes dithering, color-mask, and face culling stat
233     void flushMiscFixedFunctionState();
234
235     // flushes the scissor. see the note on flushBoundTextureAndParams about
236     // flushing the scissor after that function is called.
237     void flushScissor();
238
239     void initFSAASupport();
240
241     // determines valid stencil formats
242     void initStencilFormats();
243
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();
247
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);
254
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,
262                        bool isNewTexture,
263                        int left, int top, int width, int height,
264                        GrPixelConfig dataConfig,
265                        const void* data,
266                        size_t rowBytes);
267
268     bool createRenderTargetObjects(int width, int height,
269                                    GrGLuint texID,
270                                    GrGLRenderTarget::Desc* desc);
271
272     GrGLContext fGLContext;
273
274     // GL program-related state
275     ProgramCache*               fProgramCache;
276     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
277
278     ///////////////////////////////////////////////////////////////////////////
279     ///@name Caching of GL State
280     ///@{
281     int                         fHWActiveTextureUnitIdx;
282     GrGLuint                    fHWProgramID;
283
284     GrGLProgram::SharedGLState  fSharedGLProgramState;
285
286     enum TriState {
287         kNo_TriState,
288         kYes_TriState,
289         kUnknown_TriState
290     };
291
292     // last scissor / viewport scissor state seen by the GL.
293     struct {
294         TriState    fEnabled;
295         GrGLIRect   fRect;
296         void invalidate() {
297             fEnabled = kUnknown_TriState;
298             fRect.invalidate();
299         }
300     } fHWScissorSettings;
301
302     GrGLIRect   fHWViewport;
303
304     /**
305      * Tracks bound vertex and index buffers and vertex attrib array state.
306      */
307     class HWGeometryState {
308     public:
309         HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
310
311         ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
312
313         void invalidate() {
314             fBoundVertexArrayIDIsValid = false;
315             fBoundVertexBufferIDIsValid = false;
316             fDefaultVertexArrayBoundIndexBufferID = false;
317             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
318             fDefaultVertexArrayAttribState.invalidate();
319             if (NULL != fVBOVertexArray) {
320                 fVBOVertexArray->invalidateCachedState();
321             }
322         }
323
324         void notifyVertexArrayDelete(GrGLuint id) {
325             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
326                 // Does implicit bind to 0
327                 fBoundVertexArrayID = 0;
328             }
329         }
330
331         void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
332             if (!gpu->glCaps().vertexArrayObjectSupport()) {
333                 SkASSERT(0 == arrayID);
334                 return;
335             }
336             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
337                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
338                 fBoundVertexArrayIDIsValid = true;
339                 fBoundVertexArrayID = arrayID;
340             }
341         }
342
343         void notifyVertexBufferDelete(GrGLuint id) {
344             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
345                 fBoundVertexBufferID = 0;
346             }
347             if (NULL != fVBOVertexArray) {
348                 fVBOVertexArray->notifyVertexBufferDelete(id);
349             }
350             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
351         }
352
353         void notifyIndexBufferDelete(GrGLuint id) {
354             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
355                 id == fDefaultVertexArrayBoundIndexBufferID) {
356                 fDefaultVertexArrayBoundIndexBufferID = 0;
357             }
358             if (NULL != fVBOVertexArray) {
359                 fVBOVertexArray->notifyIndexBufferDelete(id);
360             }
361         }
362
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;
368             }
369         }
370
371         /**
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.
374          */
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;
382             }
383         }
384
385         /**
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.
390          */
391         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
392                                                         const GrGLVertexBuffer* vbuffer,
393                                                         const GrGLIndexBuffer* ibuffer);
394
395     private:
396         GrGLuint                fBoundVertexArrayID;
397         GrGLuint                fBoundVertexBufferID;
398         bool                    fBoundVertexArrayIDIsValid;
399         bool                    fBoundVertexBufferIDIsValid;
400
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
405         // GrGpuGL.
406         GrGLAttribArrayState    fDefaultVertexArrayAttribState;
407
408         // This is used when we're using a core profile and the vertices are in a VBO.
409         GrGLVertexArray*        fVBOVertexArray;
410     } fHWGeometryState;
411
412     struct {
413         GrBlendCoeff    fSrcCoeff;
414         GrBlendCoeff    fDstCoeff;
415         GrColor         fConstColor;
416         bool            fConstColorValid;
417         TriState        fEnabled;
418
419         void invalidate() {
420             fSrcCoeff = kInvalid_GrBlendCoeff;
421             fDstCoeff = kInvalid_GrBlendCoeff;
422             fConstColorValid = false;
423             fEnabled = kUnknown_TriState;
424         }
425     } fHWBlendState;
426
427     struct {
428         TriState fMSAAEnabled;
429         TriState fSmoothLineEnabled;
430         void invalidate() {
431             fMSAAEnabled = kUnknown_TriState;
432             fSmoothLineEnabled = kUnknown_TriState;
433         }
434     } fHWAAState;
435
436
437     GrGLProgram::MatrixState    fHWProjectionMatrixState;
438
439     GrStencilSettings           fHWStencilSettings;
440     TriState                    fHWStencilTestEnabled;
441     GrStencilSettings           fHWPathStencilSettings;
442
443     GrDrawState::DrawFace       fHWDrawFace;
444     TriState                    fHWWriteToColor;
445     TriState                    fHWDitherEnabled;
446     GrRenderTarget*             fHWBoundRenderTarget;
447     SkTArray<GrTexture*, true>  fHWBoundTextures;
448
449     struct PathTexGenData {
450         GrGLenum  fMode;
451         GrGLint   fNumComponents;
452         GrGLfloat fCoefficients[3 * 3];
453     };
454     int                         fHWActivePathTexGenSets;
455     SkTArray<PathTexGenData, true>  fHWPathTexGenSettings;
456     ///@}
457
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;
461
462     typedef GrGpu INHERITED;
463 };
464
465 #endif