65816b54a82849562f1717f0ccbed647f5d4c1b6
[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 "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"
21 #include "GrGpu.h"
22 #include "SkTypes.h"
23
24 #ifdef SK_DEVELOPER
25 #define PROGRAM_CACHE_STATS
26 #endif
27
28 class GrGpuGL : public GrGpu {
29 public:
30     GrGpuGL(const GrGLContext& ctx, GrContext* context);
31     virtual ~GrGpuGL();
32
33     virtual void contextAbandoned() SK_OVERRIDE;
34
35     const GrGLContext& glContext() const { return fGLContext; }
36
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(); }
43
44     GrGLPathRendering* glPathRendering() {
45         SkASSERT(glCaps().pathRenderingSupport());
46         return static_cast<GrGLPathRendering*>(pathRendering());
47     }
48
49     virtual void discard(GrRenderTarget*) SK_OVERRIDE;
50
51     // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
52     // state.
53     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
54
55     bool programUnitTest(int maxStages);
56
57     // GrGpu overrides
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,
65                                     int left, int top,
66                                     int width, int height,
67                                     GrPixelConfig config,
68                                     size_t rowBytes) const SK_OVERRIDE;
69     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
70
71     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
72
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);
77     }
78     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
79         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
80     }
81     void bindVertexBuffer(GrGLuint id) {
82         fHWGeometryState.setVertexBufferID(this, id);
83     }
84
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);
89     }
90     void notifyVertexBufferDelete(GrGLuint id) {
91         fHWGeometryState.notifyVertexBufferDelete(id);
92     }
93     void notifyIndexBufferDelete(GrGLuint id) {
94         fHWGeometryState.notifyIndexBufferDelete(id);
95     }
96
97 protected:
98     virtual bool onCopySurface(GrSurface* dst,
99                                GrSurface* src,
100                                const SkIRect& srcRect,
101                                const SkIPoint& dstPoint) SK_OVERRIDE;
102
103     virtual bool onCanCopySurface(GrSurface* dst,
104                                   GrSurface* src,
105                                   const SkIRect& srcRect,
106                                   const SkIPoint& dstPoint) SK_OVERRIDE;
107
108 private:
109     // GrGpu overrides
110     virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
111
112     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
113                                        const void* srcData,
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,
122                                                     int width,
123                                                     int height) SK_OVERRIDE;
124     virtual bool attachStencilBufferToRenderTarget(
125         GrStencilBuffer* sb,
126         GrRenderTarget* rt) SK_OVERRIDE;
127
128     virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
129                          bool canIgnoreRect) SK_OVERRIDE;
130
131     virtual bool onReadPixels(GrRenderTarget* target,
132                               int left, int top,
133                               int width, int height,
134                               GrPixelConfig,
135                               void* buffer,
136                               size_t rowBytes) SK_OVERRIDE;
137
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;
142
143     virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
144
145     virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
146
147
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;
152
153     // GrDrawTarget overrides
154     virtual void didAddGpuTraceMarker() SK_OVERRIDE;
155     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
156
157     // binds texture unit in GL
158     void setTextureUnit(int unitIdx);
159
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);
164
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);
171
172     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
173
174     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
175
176     class ProgramCache : public ::SkNoncopyable {
177     public:
178         ProgramCache(GrGpuGL* gpu);
179         ~ProgramCache();
180
181         void abandon();
182         GrGLProgram* getProgram(const GrGLProgramDesc& desc,
183                                 const GrGeometryStage* geometryProcessor,
184                                 const GrFragmentStage* colorStages[],
185                                 const GrFragmentStage* coverageStages[]);
186
187     private:
188         enum {
189             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
190             // shader before evicting from the cache.
191             kMaxEntries = 128,
192             kHashBits = 6,
193         };
194
195         struct Entry;
196
197         struct ProgDescLess;
198
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;
202
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];
208
209         int                         fCount;
210         unsigned int                fCurrLRUStamp;
211         GrGpuGL*                    fGpu;
212 #ifdef PROGRAM_CACHE_STATS
213         int                         fTotalRequests;
214         int                         fCacheMisses;
215         int                         fHashMisses; // cache hit but hash table missed
216 #endif
217     };
218
219     // flushes dithering, color-mask, and face culling stat
220     void flushMiscFixedFunctionState(const GrOptDrawState&);
221
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);
225
226     void initFSAASupport();
227
228     // determines valid stencil formats
229     void initStencilFormats();
230
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();
234
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);
238
239     void flushStencil(DrawType);
240     void flushAAState(const GrOptDrawState&, DrawType);
241
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,
249                        bool isNewTexture,
250                        int left, int top, int width, int height,
251                        GrPixelConfig dataConfig,
252                        const void* data,
253                        size_t rowBytes);
254
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
260     // with new data.
261     bool uploadCompressedTexData(const GrGLTexture::Desc& desc,
262                                  const void* data,
263                                  bool isNewTexture = true,
264                                  int left = 0, int top = 0,
265                                  int width = -1, int height = -1);
266
267     bool createRenderTargetObjects(int width, int height,
268                                    GrGLuint texID,
269                                    GrGLRenderTarget::Desc* desc);
270
271     GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
272
273     GrGLContext fGLContext;
274
275     // GL program-related state
276     ProgramCache*               fProgramCache;
277     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
278
279     ///////////////////////////////////////////////////////////////////////////
280     ///@name Caching of GL State
281     ///@{
282     int                         fHWActiveTextureUnitIdx;
283     GrGLuint                    fHWProgramID;
284
285     GrGLProgram::SharedGLState  fSharedGLProgramState;
286
287     enum TriState {
288         kNo_TriState,
289         kYes_TriState,
290         kUnknown_TriState
291     };
292
293     // last scissor / viewport scissor state seen by the GL.
294     struct {
295         TriState    fEnabled;
296         GrGLIRect   fRect;
297         void invalidate() {
298             fEnabled = kUnknown_TriState;
299             fRect.invalidate();
300         }
301     } fHWScissorSettings;
302
303     GrGLIRect   fHWViewport;
304
305     /**
306      * Tracks bound vertex and index buffers and vertex attrib array state.
307      */
308     class HWGeometryState {
309     public:
310         HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
311
312         ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
313
314         void invalidate() {
315             fBoundVertexArrayIDIsValid = false;
316             fBoundVertexBufferIDIsValid = false;
317             fDefaultVertexArrayBoundIndexBufferID = false;
318             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
319             fDefaultVertexArrayAttribState.invalidate();
320             if (fVBOVertexArray) {
321                 fVBOVertexArray->invalidateCachedState();
322             }
323         }
324
325         void notifyVertexArrayDelete(GrGLuint id) {
326             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
327                 // Does implicit bind to 0
328                 fBoundVertexArrayID = 0;
329             }
330         }
331
332         void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
333             if (!gpu->glCaps().vertexArrayObjectSupport()) {
334                 SkASSERT(0 == arrayID);
335                 return;
336             }
337             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
338                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
339                 fBoundVertexArrayIDIsValid = true;
340                 fBoundVertexArrayID = arrayID;
341             }
342         }
343
344         void notifyVertexBufferDelete(GrGLuint id) {
345             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
346                 fBoundVertexBufferID = 0;
347             }
348             if (fVBOVertexArray) {
349                 fVBOVertexArray->notifyVertexBufferDelete(id);
350             }
351             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
352         }
353
354         void notifyIndexBufferDelete(GrGLuint id) {
355             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
356                 id == fDefaultVertexArrayBoundIndexBufferID) {
357                 fDefaultVertexArrayBoundIndexBufferID = 0;
358             }
359             if (fVBOVertexArray) {
360                 fVBOVertexArray->notifyIndexBufferDelete(id);
361             }
362         }
363
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;
369             }
370         }
371
372         /**
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.
375          */
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;
383             }
384         }
385
386         /**
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.
391          */
392         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
393                                                         const GrGLVertexBuffer* vbuffer,
394                                                         const GrGLIndexBuffer* ibuffer);
395
396     private:
397         GrGLuint                fBoundVertexArrayID;
398         GrGLuint                fBoundVertexBufferID;
399         bool                    fBoundVertexArrayIDIsValid;
400         bool                    fBoundVertexBufferIDIsValid;
401
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
406         // GrGpuGL.
407         GrGLAttribArrayState    fDefaultVertexArrayAttribState;
408
409         // This is used when we're using a core profile and the vertices are in a VBO.
410         GrGLVertexArray*        fVBOVertexArray;
411     } fHWGeometryState;
412
413     struct {
414         GrBlendCoeff    fSrcCoeff;
415         GrBlendCoeff    fDstCoeff;
416         GrColor         fConstColor;
417         bool            fConstColorValid;
418         TriState        fEnabled;
419
420         void invalidate() {
421             fSrcCoeff = kInvalid_GrBlendCoeff;
422             fDstCoeff = kInvalid_GrBlendCoeff;
423             fConstColorValid = false;
424             fEnabled = kUnknown_TriState;
425         }
426     } fHWBlendState;
427
428     TriState fMSAAEnabled;
429
430     GrStencilSettings           fHWStencilSettings;
431     TriState                    fHWStencilTestEnabled;
432
433
434     GrDrawState::DrawFace       fHWDrawFace;
435     TriState                    fHWWriteToColor;
436     TriState                    fHWDitherEnabled;
437     uint32_t                    fHWBoundRenderTargetUniqueID;
438     SkTArray<uint32_t, true>    fHWBoundTextureUniqueIDs;
439
440     ///@}
441
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;
445
446     typedef GrGpu INHERITED;
447     friend class GrGLPathRendering; // For accessing setTextureUnit.
448 };
449
450 #endif