summaryrefslogtreecommitdiffstats
path: root/cc/gl_renderer.h
blob: f8651a8ef2e7631e19254a4abfb17d89cb7b40c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// Copyright 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_GL_RENDERER_H_
#define CC_GL_RENDERER_H_

#include "cc/base/cc_export.h"
#include "cc/checkerboard_draw_quad.h"
#include "cc/debug_border_draw_quad.h"
#include "cc/direct_renderer.h"
#include "cc/gl_renderer_draw_cache.h"
#include "cc/io_surface_draw_quad.h"
#include "cc/render_pass_draw_quad.h"
#include "cc/renderer.h"
#include "cc/solid_color_draw_quad.h"
#include "cc/tile_draw_quad.h"
#include "cc/yuv_video_draw_quad.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsMemoryAllocation.h"
#include "ui/gfx/quad_f.h"

namespace cc {

class GLRendererShaderTest;
class OutputSurface;
class ScopedResource;
class StreamVideoDrawQuad;
class TextureDrawQuad;
class GeometryBinding;
class ScopedEnsureFramebufferAllocation;

// Class that handles drawing of composited render layers using GL.
class CC_EXPORT GLRenderer :
    public DirectRenderer,
    public NON_EXPORTED_BASE(
        WebKit::WebGraphicsContext3D::
            WebGraphicsSwapBuffersCompleteCallbackCHROMIUM),
    public NON_EXPORTED_BASE(
        WebKit::WebGraphicsContext3D::
            WebGraphicsMemoryAllocationChangedCallbackCHROMIUM),
    public NON_EXPORTED_BASE(
        WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback) {
 public:
  static scoped_ptr<GLRenderer> Create(RendererClient* client,
                                       OutputSurface* output_surface,
                                       ResourceProvider* resource_provider);

  virtual ~GLRenderer();

  virtual const RendererCapabilities& Capabilities() const OVERRIDE;

  WebKit::WebGraphicsContext3D* Context();

  virtual void ViewportChanged() OVERRIDE;

  virtual void ReceiveCompositorFrameAck(const CompositorFrameAck& ack)
      OVERRIDE;

  // Waits for rendering to finish.
  virtual void Finish() OVERRIDE;

  virtual void DoNoOp() OVERRIDE;
  // Puts backbuffer onscreen.
  virtual bool SwapBuffers() OVERRIDE;

  virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) OVERRIDE;

  virtual bool IsContextLost() OVERRIDE;

  virtual void SetVisible(bool visible) OVERRIDE;

  virtual void SendManagedMemoryStats(size_t bytes_visible,
                                      size_t bytes_visible_and_nearby,
                                      size_t bytes_allocated) OVERRIDE;

  static void DebugGLCall(WebKit::WebGraphicsContext3D* context,
                          const char* command,
                          const char* file,
                          int line);

 protected:
  GLRenderer(RendererClient* client,
             OutputSurface* output_surface,
             ResourceProvider* resource_provider);

  bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; }
  bool Initialize();

  const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; }
  const GeometryBinding* SharedGeometry() const {
    return shared_geometry_.get();
  }

  bool GetFramebufferTexture(ScopedResource* resource, gfx::Rect device_rect);
  void ReleaseRenderPassTextures();

  virtual void BindFramebufferToOutputSurface(DrawingFrame& frame) OVERRIDE;
  virtual bool BindFramebufferToTexture(DrawingFrame& frame,
                                        const ScopedResource* resource,
                                        gfx::Rect framebuffer_rect) OVERRIDE;
  virtual void SetDrawViewportSize(gfx::Size viewport_size) OVERRIDE;
  virtual void SetScissorTestRect(gfx::Rect scissor_rect) OVERRIDE;
  virtual void ClearFramebuffer(DrawingFrame& frame) OVERRIDE;
  virtual void DoDrawQuad(DrawingFrame& frame, const class DrawQuad*) OVERRIDE;
  virtual void BeginDrawingFrame(DrawingFrame& frame) OVERRIDE;
  virtual void FinishDrawingFrame(DrawingFrame& frame) OVERRIDE;
  virtual bool FlippedFramebuffer() const OVERRIDE;
  virtual void EnsureScissorTestEnabled() OVERRIDE;
  virtual void EnsureScissorTestDisabled() OVERRIDE;
  virtual void FinishDrawingQuadList() OVERRIDE;

 private:
  friend class GLRendererShaderTest;

  static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform);
  static ManagedMemoryPolicy::PriorityCutoff PriorityCutoff(
      WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff);

  void DrawCheckerboardQuad(const DrawingFrame& frame,
                            const CheckerboardDrawQuad* quad);
  void DrawDebugBorderQuad(const DrawingFrame& frame,
                           const DebugBorderDrawQuad* quad);
  scoped_ptr<ScopedResource> DrawBackgroundFilters(
      DrawingFrame& frame,
      const RenderPassDrawQuad* quad,
      const gfx::Transform& contents_device_transform,
      const gfx::Transform& contents_device_transformInverse);
  void DrawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQuad* quad);
  void DrawSolidColorQuad(const DrawingFrame& frame,
                          const SolidColorDrawQuad* quad);
  void DrawStreamVideoQuad(const DrawingFrame& frame,
                           const StreamVideoDrawQuad* quad);
  void DrawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad);
  void EnqueueTextureQuad(const DrawingFrame& frame,
                          const TextureDrawQuad* quad);
  void FlushTextureQuadCache();
  void DrawIOSurfaceQuad(const DrawingFrame& frame,
                         const IOSurfaceDrawQuad* quad);
  void DrawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad);
  void DrawYUVVideoQuad(const DrawingFrame& frame,
                        const YUVVideoDrawQuad* quad);

  void SetShaderOpacity(float opacity, int alpha_location);
  void SetShaderQuadF(const gfx::QuadF& quad, int quad_location);
  void DrawQuadGeometry(const DrawingFrame& frame,
                        const gfx::Transform& draw_transform,
                        const gfx::RectF& quad_rect,
                        int matrix_location);
  void SetBlendEnabled(bool enabled);
  void SetUseProgram(unsigned program);

  void CopyTextureToFramebuffer(const DrawingFrame& frame,
                                int texture_id,
                                gfx::Rect rect,
                                const gfx::Transform& draw_matrix);

  // Check if quad needs antialiasing and if so, inflate the quad and
  // fill edge array for fragment shader.  localQuad is set to
  // inflated quad if antialiasing is required, otherwise it is left
  // unchanged.  edge array is filled with inflated quad's edge data
  // if antialiasing is required, otherwise it is left unchanged.
  // Returns true if quad requires antialiasing and false otherwise.
  bool SetupQuadForAntialiasing(const gfx::Transform& device_transform,
                                const DrawQuad* quad,
                                gfx::QuadF* local_quad,
                                float edge[24]) const;

  bool UseScopedTexture(DrawingFrame& frame,
                        const ScopedResource* resource,
                        gfx::Rect viewport_rect);

  bool MakeContextCurrent();

  bool InitializeSharedObjects();
  void CleanupSharedObjects();

  // WebKit::
  // WebGraphicsContext3D::WebGraphicsSwapBuffersCompleteCallbackCHROMIUM
  // implementation.
  virtual void onSwapBuffersComplete() OVERRIDE;

  // WebKit::
  // WebGraphicsContext3D::WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
  // implementation.
  virtual void onMemoryAllocationChanged(
      WebKit::WebGraphicsMemoryAllocation allocation) OVERRIDE;
  void DiscardBackbuffer();
  void EnsureBackbuffer();
  void EnforceMemoryPolicy();

  // WebGraphicsContext3D::WebGraphicsContextLostCallback implementation.
  virtual void onContextLost() OVERRIDE;

  RendererCapabilities capabilities_;

  unsigned offscreen_framebuffer_id_;

  scoped_ptr<GeometryBinding> shared_geometry_;
  gfx::QuadF shared_geometry_quad_;

  // This block of bindings defines all of the programs used by the compositor
  // itself.  Add any new programs here to GLRendererShaderTest.

  // Tiled layer shaders.
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexAlpha>
      TileProgram;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexClampAlphaAA>
      TileProgramAA;
  typedef ProgramBinding<VertexShaderTile,
                         FragmentShaderRGBATexClampSwizzleAlphaAA>
      TileProgramSwizzleAA;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexOpaque>
      TileProgramOpaque;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleAlpha>
      TileProgramSwizzle;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleOpaque>
      TileProgramSwizzleOpaque;
  typedef ProgramBinding<VertexShaderPosTex, FragmentShaderCheckerboard>
      TileCheckerboardProgram;

  // Render surface shaders.
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexAlpha> RenderPassProgram;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexAlphaMask> RenderPassMaskProgram;
  typedef ProgramBinding<VertexShaderQuad, FragmentShaderRGBATexAlphaAA>
      RenderPassProgramAA;
  typedef ProgramBinding<VertexShaderQuad, FragmentShaderRGBATexAlphaMaskAA>
      RenderPassMaskProgramAA;

  // Texture shaders.
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexVaryingAlpha> TextureProgram;
  typedef ProgramBinding<VertexShaderPosTexTransformFlip,
                         FragmentShaderRGBATexVaryingAlpha> TextureProgramFlip;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexRectVaryingAlpha>
      TextureIOSurfaceProgram;

  // Video shaders.
  typedef ProgramBinding<VertexShaderVideoTransform,
                         FragmentShaderOESImageExternal>
      VideoStreamTextureProgram;
  typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo>
      VideoYUVProgram;

  // Special purpose / effects shaders.
  typedef ProgramBinding<VertexShaderPos, FragmentShaderColor>
      DebugBorderProgram;
  typedef ProgramBinding<VertexShaderQuad, FragmentShaderColor>
      SolidColorProgram;
  typedef ProgramBinding<VertexShaderQuad, FragmentShaderColorAA>
      SolidColorProgramAA;

  const TileProgram* GetTileProgram();
  const TileProgramOpaque* GetTileProgramOpaque();
  const TileProgramAA* GetTileProgramAA();
  const TileProgramSwizzle* GetTileProgramSwizzle();
  const TileProgramSwizzleOpaque* GetTileProgramSwizzleOpaque();
  const TileProgramSwizzleAA* GetTileProgramSwizzleAA();
  const TileCheckerboardProgram* GetTileCheckerboardProgram();

  const RenderPassProgram* GetRenderPassProgram();
  const RenderPassProgramAA* GetRenderPassProgramAA();
  const RenderPassMaskProgram* GetRenderPassMaskProgram();
  const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA();

  const TextureProgram* GetTextureProgram();
  const TextureProgramFlip* GetTextureProgramFlip();
  const TextureIOSurfaceProgram* GetTextureIOSurfaceProgram();

  const VideoYUVProgram* GetVideoYUVProgram();
  const VideoStreamTextureProgram* GetVideoStreamTextureProgram();

  const DebugBorderProgram* GetDebugBorderProgram();
  const SolidColorProgram* GetSolidColorProgram();
  const SolidColorProgramAA* GetSolidColorProgramAA();

  scoped_ptr<TileProgram> tile_program_;
  scoped_ptr<TileProgramOpaque> tile_program_opaque_;
  scoped_ptr<TileProgramAA> tile_program_aa_;
  scoped_ptr<TileProgramSwizzle> tile_program_swizzle_;
  scoped_ptr<TileProgramSwizzleOpaque> tile_program_swizzle_opaque_;
  scoped_ptr<TileProgramSwizzleAA> tile_program_swizzle_aa_;
  scoped_ptr<TileCheckerboardProgram> tile_checkerboard_program_;

  scoped_ptr<RenderPassProgram> render_pass_program_;
  scoped_ptr<RenderPassProgramAA> render_pass_program_aa_;
  scoped_ptr<RenderPassMaskProgram> render_pass_mask_program_;
  scoped_ptr<RenderPassMaskProgramAA> render_pass_mask_program_aa_;

  scoped_ptr<TextureProgram> texture_program_;
  scoped_ptr<TextureProgramFlip> texture_program_flip_;
  scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_;

  scoped_ptr<VideoYUVProgram> video_yuv_program_;
  scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_;

  scoped_ptr<DebugBorderProgram> debug_border_program_;
  scoped_ptr<SolidColorProgram> solid_color_program_;
  scoped_ptr<SolidColorProgramAA> solid_color_program_aa_;

  OutputSurface* output_surface_;
  WebKit::WebGraphicsContext3D* context_;

  gfx::Rect swap_buffer_rect_;
  gfx::Rect scissor_rect_;
  bool is_viewport_changed_;
  bool is_backbuffer_discarded_;
  bool discard_backbuffer_when_not_visible_;
  bool is_using_bind_uniform_;
  bool visible_;
  bool is_scissor_enabled_;
  bool blend_shadow_;
  unsigned program_shadow_;
  TexturedQuadDrawCache draw_cache_;

  scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_;

  scoped_refptr<ResourceProvider::Fence> last_swap_fence_;

  DISALLOW_COPY_AND_ASSIGN(GLRenderer);
};

// Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL
// call made by the compositor. Useful for debugging rendering issues but
// will significantly degrade performance.
#define DEBUG_GL_CALLS 0

#if DEBUG_GL_CALLS && !defined(NDEBUG)
#define GLC(context, x)                                                        \
  (x, GLRenderer::DebugGLCall (&* context, #x, __FILE__, __LINE__))
#else
#define GLC(context, x) (x)
#endif

}

#endif  // CC_GL_RENDERER_H_