Upstream version 11.40.277.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 "GrDrawState.h"
12 #include "GrGLContext.h"
13 #include "GrGLIRect.h"
14 #include "GrGLIndexBuffer.h"
15 #include "GrGLPathRendering.h"
16 #include "GrGLProgram.h"
17 #include "GrGLRenderTarget.h"
18 #include "GrGLStencilBuffer.h"
19 #include "GrGLTexture.h"
20 #include "GrGLVertexArray.h"
21 #include "GrGLVertexBuffer.h"
22 #include "GrGpu.h"
23 #include "GrOptDrawState.h"
24 #include "SkTypes.h"
25
26 #ifdef SK_DEVELOPER
27 #define PROGRAM_CACHE_STATS
28 #endif
29
30 class GrGpuGL : public GrGpu {
31 public:
32     GrGpuGL(const GrGLContext& ctx, GrContext* context);
33     virtual ~GrGpuGL();
34
35     virtual void contextAbandoned() SK_OVERRIDE;
36
37     const GrGLContext& glContext() const { return fGLContext; }
38
39     const GrGLInterface* glInterface() const { return fGLContext.interface(); }
40     const GrGLContextInfo& ctxInfo() const { return fGLContext; }
41     GrGLStandard glStandard() const { return fGLContext.standard(); }
42     GrGLVersion glVersion() const { return fGLContext.version(); }
43     GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
44     const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
45
46     GrGLPathRendering* glPathRendering() {
47         SkASSERT(glCaps().pathRenderingSupport());
48         return static_cast<GrGLPathRendering*>(pathRendering());
49     }
50
51     virtual void discard(GrRenderTarget*) SK_OVERRIDE;
52
53     // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
54     // state.
55     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
56
57     bool programUnitTest(int maxStages);
58
59     // GrGpu overrides
60     virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
61                                                     GrPixelConfig surfaceConfig) const SK_OVERRIDE;
62     virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
63                                                      GrPixelConfig surfaceConfig) const SK_OVERRIDE;
64     virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE;
65     virtual bool readPixelsWillPayForYFlip(
66                                     GrRenderTarget* renderTarget,
67                                     int left, int top,
68                                     int width, int height,
69                                     GrPixelConfig config,
70                                     size_t rowBytes) const SK_OVERRIDE;
71     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
72
73     virtual void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) SK_OVERRIDE;
74
75     // These functions should be used to bind GL objects. They track the GL state and skip redundant
76     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
77     void bindVertexArray(GrGLuint id) {
78         fHWGeometryState.setVertexArrayID(this, id);
79     }
80     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
81         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
82     }
83     void bindVertexBuffer(GrGLuint id) {
84         fHWGeometryState.setVertexBufferID(this, id);
85     }
86
87     // These callbacks update state tracking when GL objects are deleted. They are called from
88     // GrGLResource onRelease functions.
89     void notifyVertexArrayDelete(GrGLuint id) {
90         fHWGeometryState.notifyVertexArrayDelete(id);
91     }
92     void notifyVertexBufferDelete(GrGLuint id) {
93         fHWGeometryState.notifyVertexBufferDelete(id);
94     }
95     void notifyIndexBufferDelete(GrGLuint id) {
96         fHWGeometryState.notifyIndexBufferDelete(id);
97     }
98
99     // DrawTarget overrides
100     virtual bool copySurface(GrSurface* dst,
101                              GrSurface* src,
102                              const SkIRect& srcRect,
103                              const SkIPoint& dstPoint) SK_OVERRIDE;
104
105     virtual bool canCopySurface(GrSurface* dst,
106                                 GrSurface* src,
107                                 const SkIRect& srcRect,
108                                 const SkIPoint& dstPoint) SK_OVERRIDE;
109
110 protected:
111     virtual void buildProgramDesc(const GrOptDrawState&,
112                                   const GrProgramDesc::DescInfo&,
113                                   GrGpu::DrawType,
114                                   const GrDeviceCoordTexture* dstCopy,
115                                   GrProgramDesc*) SK_OVERRIDE;
116
117 private:
118     // GrGpu overrides
119     virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
120
121     virtual GrTexture* onCreateTexture(const GrSurfaceDesc& desc,
122                                        const void* srcData,
123                                        size_t rowBytes) SK_OVERRIDE;
124     virtual GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
125                                                  const void* srcData) SK_OVERRIDE;
126     virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
127     virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) 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 onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
138                             bool canIgnoreRect) SK_OVERRIDE;
139
140     virtual void onClearStencilClip(GrRenderTarget*,
141                                     const SkIRect& rect,
142                                     bool insideClip) SK_OVERRIDE;
143
144     virtual bool onReadPixels(GrRenderTarget* target,
145                               int left, int top,
146                               int width, int height,
147                               GrPixelConfig,
148                               void* buffer,
149                               size_t rowBytes) SK_OVERRIDE;
150
151     virtual bool onWriteTexturePixels(GrTexture* texture,
152                                       int left, int top, int width, int height,
153                                       GrPixelConfig config, const void* buffer,
154                                       size_t rowBytes) SK_OVERRIDE;
155
156     virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
157
158     virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
159
160
161     virtual void clearStencil(GrRenderTarget*) SK_OVERRIDE;
162     virtual bool flushGraphicsState(DrawType,
163                                     const GrClipMaskManager::ScissorState&,
164                                     const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
165
166     // GrDrawTarget overrides
167     virtual void didAddGpuTraceMarker() SK_OVERRIDE;
168     virtual void didRemoveGpuTraceMarker() SK_OVERRIDE;
169
170     // binds texture unit in GL
171     void setTextureUnit(int unitIdx);
172
173     // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
174     // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start
175     // index is relative to the returned offset.
176     void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes);
177
178     // Subclasses should call this to flush the blend state.
179     // The params should be the final coefficients to apply
180     // (after any blending optimizations or dual source blending considerations
181     // have been accounted for).
182     void flushBlend(const GrOptDrawState& optState, bool isLines,
183                     GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
184
185     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
186
187     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
188
189     class ProgramCache : public ::SkNoncopyable {
190     public:
191         ProgramCache(GrGpuGL* gpu);
192         ~ProgramCache();
193
194         void abandon();
195         GrGLProgram* getProgram(const GrOptDrawState&, DrawType);
196
197     private:
198         enum {
199             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
200             // shader before evicting from the cache.
201             kMaxEntries = 128,
202             kHashBits = 6,
203         };
204
205         struct Entry;
206
207         struct ProgDescLess;
208
209         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
210         // of the index of where it should be inserted.
211         int search(const GrProgramDesc& desc) const;
212
213         // sorted array of all the entries
214         Entry*                      fEntries[kMaxEntries];
215         // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
216         // searching fEntries.
217         Entry*                      fHashTable[1 << kHashBits];
218
219         int                         fCount;
220         unsigned int                fCurrLRUStamp;
221         GrGpuGL*                    fGpu;
222 #ifdef PROGRAM_CACHE_STATS
223         int                         fTotalRequests;
224         int                         fCacheMisses;
225         int                         fHashMisses; // cache hit but hash table missed
226 #endif
227     };
228
229     // flushes dithering, color-mask, and face culling stat
230     void flushMiscFixedFunctionState(const GrOptDrawState&);
231
232     // flushes the scissor. see the note on flushBoundTextureAndParams about
233     // flushing the scissor after that function is called.
234     void flushScissor(const GrClipMaskManager::ScissorState&,
235                       const GrGLIRect& rtViewport,
236                       GrSurfaceOrigin rtOrigin);
237
238     // disables the scissor
239     void disableScissor();
240
241     void initFSAASupport();
242
243     // determines valid stencil formats
244     void initStencilFormats();
245
246     // sets a texture unit to use for texture operations other than binding a texture to a program.
247     // ensures that such operations don't negatively interact with tracking bound textures.
248     void setScratchTextureUnit();
249
250     // bounds is region that may be modified and therefore has to be resolved.
251     // NULL means whole target. Can be an empty rect.
252     void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
253
254     void flushStencil(const GrStencilSettings&, DrawType);
255     void flushAAState(const GrOptDrawState&, DrawType);
256
257     bool configToGLFormats(GrPixelConfig config,
258                            bool getSizedInternal,
259                            GrGLenum* internalFormat,
260                            GrGLenum* externalFormat,
261                            GrGLenum* externalType);
262     // helper for onCreateTexture and writeTexturePixels
263     bool uploadTexData(const GrSurfaceDesc& desc,
264                        bool isNewTexture,
265                        int left, int top, int width, int height,
266                        GrPixelConfig dataConfig,
267                        const void* data,
268                        size_t rowBytes);
269
270     // helper for onCreateCompressedTexture. If width and height are
271     // set to -1, then this function will use desc.fWidth and desc.fHeight
272     // for the size of the data. The isNewTexture flag should be set to true
273     // whenever a new texture needs to be created. Otherwise, we assume that
274     // the texture is already in GPU memory and that it's going to be updated
275     // with new data.
276     bool uploadCompressedTexData(const GrSurfaceDesc& desc,
277                                  const void* data,
278                                  bool isNewTexture = true,
279                                  int left = 0, int top = 0,
280                                  int width = -1, int height = -1);
281
282     bool createRenderTargetObjects(const GrSurfaceDesc&, GrGLuint texID, GrGLRenderTarget::IDDesc*);
283
284     GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport);
285
286     GrGLContext fGLContext;
287
288     // GL program-related state
289     ProgramCache*               fProgramCache;
290     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
291
292     ///////////////////////////////////////////////////////////////////////////
293     ///@name Caching of GL State
294     ///@{
295     int                         fHWActiveTextureUnitIdx;
296     GrGLuint                    fHWProgramID;
297
298     enum TriState {
299         kNo_TriState,
300         kYes_TriState,
301         kUnknown_TriState
302     };
303
304     // last scissor / viewport scissor state seen by the GL.
305     struct {
306         TriState    fEnabled;
307         GrGLIRect   fRect;
308         void invalidate() {
309             fEnabled = kUnknown_TriState;
310             fRect.invalidate();
311         }
312     } fHWScissorSettings;
313
314     GrGLIRect   fHWViewport;
315
316     /**
317      * Tracks bound vertex and index buffers and vertex attrib array state.
318      */
319     class HWGeometryState {
320     public:
321         HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
322
323         ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); }
324
325         void invalidate() {
326             fBoundVertexArrayIDIsValid = false;
327             fBoundVertexBufferIDIsValid = false;
328             fDefaultVertexArrayBoundIndexBufferID = false;
329             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
330             fDefaultVertexArrayAttribState.invalidate();
331             if (fVBOVertexArray) {
332                 fVBOVertexArray->invalidateCachedState();
333             }
334         }
335
336         void notifyVertexArrayDelete(GrGLuint id) {
337             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
338                 // Does implicit bind to 0
339                 fBoundVertexArrayID = 0;
340             }
341         }
342
343         void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) {
344             if (!gpu->glCaps().vertexArrayObjectSupport()) {
345                 SkASSERT(0 == arrayID);
346                 return;
347             }
348             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
349                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
350                 fBoundVertexArrayIDIsValid = true;
351                 fBoundVertexArrayID = arrayID;
352             }
353         }
354
355         void notifyVertexBufferDelete(GrGLuint id) {
356             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
357                 fBoundVertexBufferID = 0;
358             }
359             if (fVBOVertexArray) {
360                 fVBOVertexArray->notifyVertexBufferDelete(id);
361             }
362             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
363         }
364
365         void notifyIndexBufferDelete(GrGLuint id) {
366             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
367                 id == fDefaultVertexArrayBoundIndexBufferID) {
368                 fDefaultVertexArrayBoundIndexBufferID = 0;
369             }
370             if (fVBOVertexArray) {
371                 fVBOVertexArray->notifyIndexBufferDelete(id);
372             }
373         }
374
375         void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) {
376             if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
377                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
378                 fBoundVertexBufferIDIsValid = true;
379                 fBoundVertexBufferID = id;
380             }
381         }
382
383         /**
384          * Binds the default vertex array and binds the index buffer. This is used when binding
385          * an index buffer in order to update it.
386          */
387         void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) {
388             this->setVertexArrayID(gpu, 0);
389             if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
390                 id != fDefaultVertexArrayBoundIndexBufferID) {
391                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
392                 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
393                 fDefaultVertexArrayBoundIndexBufferID = id;
394             }
395         }
396
397         /**
398          * Binds the vertex array object that should be used to render from the vertex buffer.
399          * The vertex array is bound and its attrib array state object is returned. The vertex
400          * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
401          * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
402          */
403         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu,
404                                                         const GrGLVertexBuffer* vbuffer,
405                                                         const GrGLIndexBuffer* ibuffer);
406
407     private:
408         GrGLuint                fBoundVertexArrayID;
409         GrGLuint                fBoundVertexBufferID;
410         bool                    fBoundVertexArrayIDIsValid;
411         bool                    fBoundVertexBufferIDIsValid;
412
413         GrGLuint                fDefaultVertexArrayBoundIndexBufferID;
414         bool                    fDefaultVertexArrayBoundIndexBufferIDIsValid;
415         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
416         // is bound. However, this class is internal to GrGpuGL and this object never leaks out of
417         // GrGpuGL.
418         GrGLAttribArrayState    fDefaultVertexArrayAttribState;
419
420         // This is used when we're using a core profile and the vertices are in a VBO.
421         GrGLVertexArray*        fVBOVertexArray;
422     } fHWGeometryState;
423
424     struct {
425         GrBlendCoeff    fSrcCoeff;
426         GrBlendCoeff    fDstCoeff;
427         GrColor         fConstColor;
428         bool            fConstColorValid;
429         TriState        fEnabled;
430
431         void invalidate() {
432             fSrcCoeff = kInvalid_GrBlendCoeff;
433             fDstCoeff = kInvalid_GrBlendCoeff;
434             fConstColorValid = false;
435             fEnabled = kUnknown_TriState;
436         }
437     } fHWBlendState;
438
439     TriState fMSAAEnabled;
440
441     GrStencilSettings           fHWStencilSettings;
442     TriState                    fHWStencilTestEnabled;
443
444
445     GrOptDrawState::DrawFace    fHWDrawFace;
446     TriState                    fHWWriteToColor;
447     TriState                    fHWDitherEnabled;
448     uint32_t                    fHWBoundRenderTargetUniqueID;
449     SkTArray<uint32_t, true>    fHWBoundTextureUniqueIDs;
450
451     ///@}
452
453     // we record what stencil format worked last time to hopefully exit early
454     // from our loop that tries stencil formats and calls check fb status.
455     int fLastSuccessfulStencilFmtIdx;
456
457     typedef GrGpu INHERITED;
458     friend class GrGLPathRendering; // For accessing setTextureUnit.
459 };
460
461 #endif