summaryrefslogtreecommitdiff
path: root/chromium/cc/output/gl_renderer.h
blob: ab95931a1f58f674e98a67ac3d31b06534980239 (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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
// 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_OUTPUT_GL_RENDERER_H_
#define CC_OUTPUT_GL_RENDERER_H_

#include "base/cancelable_callback.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
#include "cc/output/direct_renderer.h"
#include "cc/output/gl_renderer_draw_cache.h"
#include "cc/output/program_binding.h"
#include "cc/output/renderer.h"
#include "cc/quads/checkerboard_draw_quad.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/io_surface_draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "ui/gfx/quad_f.h"

class SkBitmap;

namespace blink { class WebGraphicsContext3D; }

namespace gpu {
namespace gles2 {
class GLES2Interface;
}
}

namespace cc {

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

// Class that handles drawing of composited render layers using GL.
class CC_EXPORT GLRenderer : public DirectRenderer {
 public:
  static scoped_ptr<GLRenderer> Create(
      RendererClient* client,
      const LayerTreeSettings* settings,
      OutputSurface* output_surface,
      ResourceProvider* resource_provider,
      TextureMailboxDeleter* texture_mailbox_deleter,
      int highp_threshold_min);

  virtual ~GLRenderer();

  virtual const RendererCapabilitiesImpl& Capabilities() const OVERRIDE;

  blink::WebGraphicsContext3D* Context();

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

  virtual void DoNoOp() OVERRIDE;
  virtual void SwapBuffers(const CompositorFrameMetadata& metadata) 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(gpu::gles2::GLES2Interface* gl,
                          const char* command,
                          const char* file,
                          int line);

 protected:
  GLRenderer(RendererClient* client,
             const LayerTreeSettings* settings,
             OutputSurface* output_surface,
             ResourceProvider* resource_provider,
             TextureMailboxDeleter* texture_mailbox_deleter,
             int highp_threshold_min);

  bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; }
  void InitializeGrContext();

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

  void GetFramebufferPixelsAsync(gfx::Rect rect,
                                 scoped_ptr<CopyOutputRequest> request);
  void GetFramebufferTexture(unsigned texture_id,
                             ResourceFormat texture_format,
                             gfx::Rect device_rect);
  void ReleaseRenderPassTextures();

  void SetStencilEnabled(bool enabled);
  bool stencil_enabled() const { return stencil_shadow_; }
  void SetBlendEnabled(bool enabled);
  bool blend_enabled() const { return blend_shadow_; }

  virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) OVERRIDE;
  virtual bool BindFramebufferToTexture(DrawingFrame* frame,
                                        const ScopedResource* resource,
                                        gfx::Rect target_rect) OVERRIDE;
  virtual void SetDrawViewport(gfx::Rect window_space_viewport) OVERRIDE;
  virtual void SetScissorTestRect(gfx::Rect scissor_rect) OVERRIDE;
  virtual void DiscardPixels(bool has_external_stencil_test,
                             bool draw_rect_covers_full_surface) OVERRIDE;
  virtual void ClearFramebuffer(DrawingFrame* frame,
                                bool has_external_stencil_test) 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 CopyCurrentRenderPassToBitmap(
      DrawingFrame* frame,
      scoped_ptr<CopyOutputRequest> request) OVERRIDE;
  virtual void FinishDrawingQuadList() OVERRIDE;

  // Check if quad needs antialiasing and if so, inflate the quad and
  // fill edge array for fragment shader.  local_quad 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.
  static bool SetupQuadForAntialiasing(const gfx::Transform& device_transform,
                                       const DrawQuad* quad,
                                       gfx::QuadF* local_quad,
                                       float edge[24]);

 private:
  friend class GLRendererShaderPixelTest;
  friend class GLRendererShaderTest;

  static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform);

  void DrawCheckerboardQuad(const DrawingFrame* frame,
                            const CheckerboardDrawQuad* quad);
  void DrawDebugBorderQuad(const DrawingFrame* frame,
                           const DebugBorderDrawQuad* quad);
  scoped_ptr<ScopedResource> GetBackgroundWithFilters(
      DrawingFrame* frame,
      const RenderPassDrawQuad* quad,
      const gfx::Transform& contents_device_transform,
      const gfx::Transform& contents_device_transformInverse,
      bool* background_changed);
  void DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quad);
  void DrawSolidColorQuad(const DrawingFrame* frame,
                          const SolidColorDrawQuad* quad);
  void DrawStreamVideoQuad(const DrawingFrame* frame,
                           const StreamVideoDrawQuad* 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 DrawContentQuad(const DrawingFrame* frame,
                       const ContentDrawQuadBase* quad,
                       ResourceProvider::ResourceId resource_id);
  void DrawYUVVideoQuad(const DrawingFrame* frame,
                        const YUVVideoDrawQuad* quad);
  void DrawPictureQuad(const DrawingFrame* frame,
                       const PictureDrawQuad* 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 SetUseProgram(unsigned program);

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

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

  bool MakeContextCurrent();

  void InitializeSharedObjects();
  void CleanupSharedObjects();

  typedef base::Callback<void(scoped_ptr<CopyOutputRequest> copy_request,
                              bool success)>
      AsyncGetFramebufferPixelsCleanupCallback;
  void DoGetFramebufferPixels(
      uint8* pixels,
      gfx::Rect window_rect,
      const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback);
  void FinishedReadback(
      const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback,
      unsigned source_buffer,
      unsigned query,
      uint8_t* dest_pixels,
      gfx::Size size);
  void PassOnSkBitmap(scoped_ptr<SkBitmap> bitmap,
                      scoped_ptr<SkAutoLockPixels> lock,
                      scoped_ptr<CopyOutputRequest> request,
                      bool success);

  void ReinitializeGLState();

  virtual void DiscardBackbuffer() OVERRIDE;
  virtual void EnsureBackbuffer() OVERRIDE;
  void EnforceMemoryPolicy();

  RendererCapabilitiesImpl 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<VertexShaderTileAA, FragmentShaderRGBATexClampAlphaAA>
      TileProgramAA;
  typedef ProgramBinding<VertexShaderTileAA,
                         FragmentShaderRGBATexClampSwizzleAlphaAA>
      TileProgramSwizzleAA;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexOpaque>
      TileProgramOpaque;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleAlpha>
      TileProgramSwizzle;
  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleOpaque>
      TileProgramSwizzleOpaque;
  typedef ProgramBinding<VertexShaderPosTex, FragmentShaderCheckerboard>
      TileCheckerboardProgram;

  // Texture shaders.
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexVaryingAlpha> TextureProgram;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexPremultiplyAlpha>
      NonPremultipliedTextureProgram;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderTexBackgroundVaryingAlpha>
      TextureBackgroundProgram;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderTexBackgroundPremultiplyAlpha>
      NonPremultipliedTextureBackgroundProgram;

  // Render surface shaders.
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexAlpha> RenderPassProgram;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexAlphaMask> RenderPassMaskProgram;
  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
                         FragmentShaderRGBATexAlphaAA> RenderPassProgramAA;
  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
                         FragmentShaderRGBATexAlphaMaskAA>
      RenderPassMaskProgramAA;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexColorMatrixAlpha>
      RenderPassColorMatrixProgram;
  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
                         FragmentShaderRGBATexAlphaMaskColorMatrixAA>
      RenderPassMaskColorMatrixProgramAA;
  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
                         FragmentShaderRGBATexAlphaColorMatrixAA>
      RenderPassColorMatrixProgramAA;
  typedef ProgramBinding<VertexShaderPosTexTransform,
                         FragmentShaderRGBATexAlphaMaskColorMatrix>
      RenderPassMaskColorMatrixProgram;

  // Video shaders.
  typedef ProgramBinding<VertexShaderVideoTransform, FragmentShaderRGBATex>
      VideoStreamTextureProgram;
  typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo>
      VideoYUVProgram;
  typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVAVideo>
      VideoYUVAProgram;

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

  const TileProgram* GetTileProgram(
      TexCoordPrecision precision, SamplerType sampler);
  const TileProgramOpaque* GetTileProgramOpaque(
      TexCoordPrecision precision, SamplerType sampler);
  const TileProgramAA* GetTileProgramAA(
      TexCoordPrecision precision, SamplerType sampler);
  const TileProgramSwizzle* GetTileProgramSwizzle(
      TexCoordPrecision precision, SamplerType sampler);
  const TileProgramSwizzleOpaque* GetTileProgramSwizzleOpaque(
      TexCoordPrecision precision, SamplerType sampler);
  const TileProgramSwizzleAA* GetTileProgramSwizzleAA(
      TexCoordPrecision precision, SamplerType sampler);

  const TileCheckerboardProgram* GetTileCheckerboardProgram();

  const RenderPassProgram* GetRenderPassProgram(
      TexCoordPrecision precision);
  const RenderPassProgramAA* GetRenderPassProgramAA(
      TexCoordPrecision precision);
  const RenderPassMaskProgram* GetRenderPassMaskProgram(
      TexCoordPrecision precision);
  const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(
      TexCoordPrecision precision);
  const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram(
      TexCoordPrecision precision);
  const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA(
      TexCoordPrecision precision);
  const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram(
      TexCoordPrecision precision);
  const RenderPassMaskColorMatrixProgramAA*
      GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision);

  const TextureProgram* GetTextureProgram(
      TexCoordPrecision precision);
  const NonPremultipliedTextureProgram* GetNonPremultipliedTextureProgram(
      TexCoordPrecision precision);
  const TextureBackgroundProgram* GetTextureBackgroundProgram(
      TexCoordPrecision precision);
  const NonPremultipliedTextureBackgroundProgram*
      GetNonPremultipliedTextureBackgroundProgram(TexCoordPrecision precision);
  const TextureProgram* GetTextureIOSurfaceProgram(
      TexCoordPrecision precision);

  const VideoYUVProgram* GetVideoYUVProgram(
      TexCoordPrecision precision);
  const VideoYUVAProgram* GetVideoYUVAProgram(
      TexCoordPrecision precision);
  const VideoStreamTextureProgram* GetVideoStreamTextureProgram(
      TexCoordPrecision precision);

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

  TileProgram tile_program_[NumTexCoordPrecisions][NumSamplerTypes];
  TileProgramOpaque
      tile_program_opaque_[NumTexCoordPrecisions][NumSamplerTypes];
  TileProgramAA tile_program_aa_[NumTexCoordPrecisions][NumSamplerTypes];
  TileProgramSwizzle
      tile_program_swizzle_[NumTexCoordPrecisions][NumSamplerTypes];
  TileProgramSwizzleOpaque
      tile_program_swizzle_opaque_[NumTexCoordPrecisions][NumSamplerTypes];
  TileProgramSwizzleAA
      tile_program_swizzle_aa_[NumTexCoordPrecisions][NumSamplerTypes];

  TileCheckerboardProgram tile_checkerboard_program_;

  TextureProgram texture_program_[NumTexCoordPrecisions];
  NonPremultipliedTextureProgram
      nonpremultiplied_texture_program_[NumTexCoordPrecisions];
  TextureBackgroundProgram texture_background_program_[NumTexCoordPrecisions];
  NonPremultipliedTextureBackgroundProgram
      nonpremultiplied_texture_background_program_[NumTexCoordPrecisions];
  TextureProgram texture_io_surface_program_[NumTexCoordPrecisions];

  RenderPassProgram render_pass_program_[NumTexCoordPrecisions];
  RenderPassProgramAA render_pass_program_aa_[NumTexCoordPrecisions];
  RenderPassMaskProgram render_pass_mask_program_[NumTexCoordPrecisions];
  RenderPassMaskProgramAA render_pass_mask_program_aa_[NumTexCoordPrecisions];
  RenderPassColorMatrixProgram
      render_pass_color_matrix_program_[NumTexCoordPrecisions];
  RenderPassColorMatrixProgramAA
      render_pass_color_matrix_program_aa_[NumTexCoordPrecisions];
  RenderPassMaskColorMatrixProgram
      render_pass_mask_color_matrix_program_[NumTexCoordPrecisions];
  RenderPassMaskColorMatrixProgramAA
      render_pass_mask_color_matrix_program_aa_[NumTexCoordPrecisions];

  VideoYUVProgram video_yuv_program_[NumTexCoordPrecisions];
  VideoYUVAProgram video_yuva_program_[NumTexCoordPrecisions];
  VideoStreamTextureProgram
      video_stream_texture_program_[NumTexCoordPrecisions];

  DebugBorderProgram debug_border_program_;
  SolidColorProgram solid_color_program_;
  SolidColorProgramAA solid_color_program_aa_;

  blink::WebGraphicsContext3D* context_;
  gpu::gles2::GLES2Interface* gl_;
  gpu::ContextSupport* context_support_;

  skia::RefPtr<GrContext> gr_context_;
  skia::RefPtr<SkCanvas> sk_canvas_;

  TextureMailboxDeleter* texture_mailbox_deleter_;

  gfx::Rect swap_buffer_rect_;
  gfx::Rect scissor_rect_;
  gfx::Rect viewport_;
  bool is_backbuffer_discarded_;
  bool is_using_bind_uniform_;
  bool visible_;
  bool is_scissor_enabled_;
  bool scissor_rect_needs_reset_;
  bool stencil_shadow_;
  bool blend_shadow_;
  unsigned program_shadow_;
  TexturedQuadDrawCache draw_cache_;
  int highp_threshold_min_;
  int highp_threshold_cache_;

  struct PendingAsyncReadPixels;
  ScopedPtrVector<PendingAsyncReadPixels> pending_async_read_pixels_;

  scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_;

  scoped_refptr<ResourceProvider::Fence> last_swap_fence_;

  SkBitmap on_demand_tile_raster_bitmap_;
  ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;

  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

}  // namespace cc

#endif  // CC_OUTPUT_GL_RENDERER_H_