Upstream version 5.34.92.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     // 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
52     };
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();
59     }
60
61     bool programUnitTest(int maxStages);
62
63     // GrGpu overrides
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,
71                                     int left, int top,
72                                     int width, int height,
73                                     GrPixelConfig config,
74                                     size_t rowBytes) const SK_OVERRIDE;
75     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
76
77     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
78
79     virtual void abandonResources() SK_OVERRIDE;
80
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);
85     }
86     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
87         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
88     }
89     void bindVertexBuffer(GrGLuint id) {
90         fHWGeometryState.setVertexBufferID(this, id);
91     }
92
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);
97     }
98     void notifyVertexBufferDelete(GrGLuint id) {
99         fHWGeometryState.notifyVertexBufferDelete(id);
100     }
101     void notifyIndexBufferDelete(GrGLuint id) {
102         fHWGeometryState.notifyIndexBufferDelete(id);
103     }
104     void notifyTextureDelete(GrGLTexture* texture);
105     void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
106
107 protected:
108     virtual bool onCopySurface(GrSurface* dst,
109                                GrSurface* src,
110                                const SkIRect& srcRect,
111                                const SkIPoint& dstPoint) SK_OVERRIDE;
112
113     virtual bool onCanCopySurface(GrSurface* dst,
114                                   GrSurface* src,
115                                   const SkIRect& srcRect,
116                                   const SkIPoint& dstPoint) SK_OVERRIDE;
117
118 private:
119     // GrGpu overrides
120     virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
121
122     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
123                                        const void* srcData,
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,
131                                                     int width,
132                                                     int height) SK_OVERRIDE;
133     virtual bool attachStencilBufferToRenderTarget(
134         GrStencilBuffer* sb,
135         GrRenderTarget* rt) SK_OVERRIDE;
136
137     virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) SK_OVERRIDE;
138
139     virtual void onForceRenderTargetFlush() 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
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;
164
165     // binds texture unit in GL
166     void setTextureUnit(int unitIdx);
167
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);
172
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);
178
179     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
180
181     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
182
183     class ProgramCache : public ::SkNoncopyable {
184     public:
185         ProgramCache(GrGpuGL* gpu);
186         ~ProgramCache();
187
188         void abandon();
189         GrGLProgram* getProgram(const GrGLProgramDesc& desc,
190                                 const GrEffectStage* colorStages[],
191                                 const GrEffectStage* coverageStages[]);
192
193     private:
194         enum {
195             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
196             // shader before evicting from the cache.
197             kMaxEntries = 32,
198             kHashBits = 6,
199         };
200
201         struct Entry;
202
203         struct ProgDescLess;
204
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;
208
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];
214
215         int                         fCount;
216         unsigned int                fCurrLRUStamp;
217         GrGpuGL*                    fGpu;
218 #ifdef PROGRAM_CACHE_STATS
219         int                         fTotalRequests;
220         int                         fCacheMisses;
221         int                         fHashMisses; // cache hit but hash table missed
222 #endif
223     };
224
225     // flushes dithering, color-mask, and face culling stat
226     void flushMiscFixedFunctionState();
227
228     // flushes the scissor. see the note on flushBoundTextureAndParams about
229     // flushing the scissor after that function is called.
230     void flushScissor();
231
232     void initFSAASupport();
233
234     // determines valid stencil formats
235     void initStencilFormats();
236
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();
240
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);
247
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,
255                        bool isNewTexture,
256                        int left, int top, int width, int height,
257                        GrPixelConfig dataConfig,
258                        const void* data,
259                        size_t rowBytes);
260
261     bool createRenderTargetObjects(int width, int height,
262                                    GrGLuint texID,
263                                    GrGLRenderTarget::Desc* desc);
264
265     GrGLContext fGLContext;
266
267     // GL program-related state
268     ProgramCache*               fProgramCache;
269     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
270
271     ///////////////////////////////////////////////////////////////////////////
272     ///@name Caching of GL State
273     ///@{
274     int                         fHWActiveTextureUnitIdx;
275     GrGLuint                    fHWProgramID;
276
277     GrGLProgram::SharedGLState  fSharedGLProgramState;
278
279     enum TriState {
280         kNo_TriState,
281         kYes_TriState,
282         kUnknown_TriState
283     };
284
285     // last scissor / viewport scissor state seen by the GL.
286     struct {
287         TriState    fEnabled;
288         GrGLIRect   fRect;
289         void invalidate() {
290             fEnabled = kUnknown_TriState;
291             fRect.invalidate();
292         }
293     } fHWScissorSettings;
294
295     GrGLIRect   fHWViewport;
296
297     /**
298      * Tracks bound vertex and index buffers and vertex attrib array state.
299      */
300     class HWGeometryState {
301     public:
302         HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
303
304         ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
305
306         void invalidate() {
307             fBoundVertexArrayIDIsValid = false;
308             fBoundVertexBufferIDIsValid = false;
309             fDefaultVertexArrayBoundIndexBufferID = false;
310             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
311             fDefaultVertexArrayAttribState.invalidate();
312             if (NULL != fVBOVertexArray) {
313                 fVBOVertexArray->invalidateCachedState();
314             }
315         }
316
317         void notifyVertexArrayDelete(GrGLuint id) {
318             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
319                 // Does implicit bind to 0
320                 fBoundVertexArrayID = 0;
321             }
322         }
323
324         void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
325             if (!gpu->glCaps().vertexArrayObjectSupport()) {
326                 SkASSERT(0 == arrayID);
327                 return;
328             }
329             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
330                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
331                 fBoundVertexArrayIDIsValid = true;
332                 fBoundVertexArrayID = arrayID;
333             }
334         }
335
336         void notifyVertexBufferDelete(GrGLuint id) {
337             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
338                 fBoundVertexBufferID = 0;
339             }
340             if (NULL != fVBOVertexArray) {
341                 fVBOVertexArray->notifyVertexBufferDelete(id);
342             }
343             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
344         }
345
346         void notifyIndexBufferDelete(GrGLuint id) {
347             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
348                 id == fDefaultVertexArrayBoundIndexBufferID) {
349                 fDefaultVertexArrayBoundIndexBufferID = 0;
350             }
351             if (NULL != fVBOVertexArray) {
352                 fVBOVertexArray->notifyIndexBufferDelete(id);
353             }
354         }
355
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;
361             }
362         }
363
364         /**
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.
367          */
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;
375             }
376         }
377
378         /**
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.
383          */
384         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
385                                                         const GrGLVertexBuffer* vbuffer,
386                                                         const GrGLIndexBuffer* ibuffer);
387
388     private:
389         GrGLuint                fBoundVertexArrayID;
390         GrGLuint                fBoundVertexBufferID;
391         bool                    fBoundVertexArrayIDIsValid;
392         bool                    fBoundVertexBufferIDIsValid;
393
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
398         // GrGpuGL.
399         GrGLAttribArrayState    fDefaultVertexArrayAttribState;
400
401         // This is used when we're using a core profile and the vertices are in a VBO.
402         GrGLVertexArray*        fVBOVertexArray;
403     } fHWGeometryState;
404
405     struct {
406         GrBlendCoeff    fSrcCoeff;
407         GrBlendCoeff    fDstCoeff;
408         GrColor         fConstColor;
409         bool            fConstColorValid;
410         TriState        fEnabled;
411
412         void invalidate() {
413             fSrcCoeff = kInvalid_GrBlendCoeff;
414             fDstCoeff = kInvalid_GrBlendCoeff;
415             fConstColorValid = false;
416             fEnabled = kUnknown_TriState;
417         }
418     } fHWBlendState;
419
420     struct {
421         TriState fMSAAEnabled;
422         TriState fSmoothLineEnabled;
423         void invalidate() {
424             fMSAAEnabled = kUnknown_TriState;
425             fSmoothLineEnabled = kUnknown_TriState;
426         }
427     } fHWAAState;
428
429
430     GrGLProgram::MatrixState    fHWProjectionMatrixState;
431
432     GrStencilSettings           fHWStencilSettings;
433     TriState                    fHWStencilTestEnabled;
434     GrStencilSettings           fHWPathStencilSettings;
435
436     GrDrawState::DrawFace       fHWDrawFace;
437     TriState                    fHWWriteToColor;
438     TriState                    fHWDitherEnabled;
439     GrRenderTarget*             fHWBoundRenderTarget;
440     SkTArray<GrTexture*, true>  fHWBoundTextures;
441
442     struct TexGenData {
443         GrGLenum  fMode;
444         GrGLint   fNumComponents;
445         GrGLfloat fCoefficients[3 * 3];
446     };
447     int                         fHWActiveTexGenSets;
448     SkTArray<TexGenData, true>  fHWTexGenSettings;
449     ///@}
450
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;
454
455     typedef GrGpu INHERITED;
456 };
457
458 #endif