blob: 26f28d0cc11c08833cdb54672a029b0aa4cc2b54 [file] [log] [blame]
// 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_