summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
blob: 26f28d0cc11c08833cdb54672a029b0aa4cc2b54 (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
// Copyright 2017 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_XR_WEBGL_DRAWING_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_XR_WEBGL_DRAWING_BUFFER_H_

#include "base/macros.h"
#include "cc/layers/texture_layer_client.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"

namespace blink {

class DrawingBuffer;
class StaticBitmapImage;

class PLATFORM_EXPORT XRWebGLDrawingBuffer
    : public RefCounted<XRWebGLDrawingBuffer> {
 public:
  static scoped_refptr<XRWebGLDrawingBuffer> Create(DrawingBuffer*,
                                                    GLuint framebuffer,
                                                    const IntSize&,
                                                    bool want_alpha_channel,
                                                    bool want_depth_buffer,
                                                    bool want_stencil_buffer,
                                                    bool want_antialiasing);

  gpu::gles2::GLES2Interface* ContextGL();
  bool ContextLost();

  const IntSize& size() const { return size_; }

  bool antialias() const { return anti_aliasing_mode_ != kNone; }
  bool depth() const { return depth_; }
  bool stencil() const { return stencil_; }
  bool alpha() const { return alpha_; }

  void Resize(const IntSize&);

  scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();

  void UseSharedBuffer(const gpu::MailboxHolder&);
  void DoneWithSharedBuffer();

  // Prepare for destruction by breaking reference loops. This must be called to
  // avoid memory leaks, drawing buffer and color buffers are refcounted and
  // store references to each other.
  void BeginDestruction();

 private:
  struct PLATFORM_EXPORT ColorBuffer
      : public base::RefCountedThreadSafe<ColorBuffer> {
    ColorBuffer(base::WeakPtr<XRWebGLDrawingBuffer>,
                const IntSize&,
                const gpu::Mailbox& mailbox,
                GLuint texture_id);
    ~ColorBuffer();

    // The thread on which the ColorBuffer is created and the DrawingBuffer is
    // bound to.
    const base::PlatformThreadRef owning_thread_ref;

    // The owning XRWebGLDrawingBuffer. Note that DrawingBuffer is explicitly
    // destroyed by the BeginDestruction method, which will eventually drain all
    // of its ColorBuffers.
    base::WeakPtr<XRWebGLDrawingBuffer> drawing_buffer;
    const IntSize size;

    // The id of the texture that imports the shared image into the
    // DrawingBuffer's context.
    const GLuint texture_id = 0;

    // The mailbox pointing to the shared image backing this color buffer.
    const gpu::Mailbox mailbox;

    // The sync token for when this buffer was sent to the compositor.
    gpu::SyncToken produce_sync_token;

    // The sync token for when this buffer was received back from the
    // compositor.
    gpu::SyncToken receive_sync_token;

   private:
    DISALLOW_COPY_AND_ASSIGN(ColorBuffer);
  };

  XRWebGLDrawingBuffer(DrawingBuffer*,
                       GLuint framebuffer,
                       bool discard_framebuffer_supported,
                       bool want_alpha_channel,
                       bool want_depth_buffer,
                       bool want_stencil_buffer);

  bool Initialize(const IntSize&, bool use_multisampling);

  IntSize AdjustSize(const IntSize&);

  scoped_refptr<ColorBuffer> CreateColorBuffer();
  scoped_refptr<ColorBuffer> CreateOrRecycleColorBuffer();

  bool WantExplicitResolve() const;
  void BindAndResolveDestinationFramebuffer();
  void SwapColorBuffers();

  void ClearBoundFramebuffer();

  static void NotifyMailboxReleased(scoped_refptr<ColorBuffer>,
                                    const gpu::SyncToken&,
                                    bool lost_resource);
  void MailboxReleased(scoped_refptr<ColorBuffer>, bool lost_resource);

  // Reference to the DrawingBuffer that owns the GL context for this object.
  scoped_refptr<DrawingBuffer> drawing_buffer_;

  const GLuint framebuffer_ = 0;
  GLuint resolved_framebuffer_ = 0;
  GLuint multisample_renderbuffer_ = 0;
  scoped_refptr<ColorBuffer> back_color_buffer_;
  scoped_refptr<ColorBuffer> front_color_buffer_;
  GLuint depth_stencil_buffer_ = 0;
  IntSize size_;

  // Nonzero for shared buffer mode from UseSharedBuffer until
  // DoneWithSharedBuffer.
  GLuint shared_buffer_texture_id_ = 0;

  // Checking framebuffer completeness is extremely expensive, it's basically a
  // glFinish followed by a synchronous wait for a reply. Do so only once per
  // code path, and only in DCHECK mode.
  bool framebuffer_complete_checked_for_resize_ = false;
  bool framebuffer_complete_checked_for_swap_ = false;
  bool framebuffer_complete_checked_for_sharedbuffer_ = false;

  // Color buffers that were released by the XR compositor can be used again.
  Deque<scoped_refptr<ColorBuffer>> recycled_color_buffer_queue_;

  bool discard_framebuffer_supported_;
  bool depth_;
  bool stencil_;
  bool alpha_;

  enum AntialiasingMode {
    kNone,
    kMSAAImplicitResolve,
    kMSAAExplicitResolve,
  };

  AntialiasingMode anti_aliasing_mode_ = kNone;

  int max_texture_size_ = 0;
  int sample_count_ = 0;

  base::WeakPtrFactory<XRWebGLDrawingBuffer> weak_factory_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_XR_WEBGL_DRAWING_BUFFER_H_