blob: 3fb37929dda459d5abe26b196d31d691f33e6410 [file] [log] [blame]
/*
* Copyright (c) 2010, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DRAWING_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DRAWING_BUFFER_H_
#include <limits>
#include <memory>
#include "base/containers/span.h"
#include "base/functional/function_ref.h"
#include "cc/layers/texture_layer_client.h"
#include "cc/resources/cross_thread_shared_bitmap.h"
#include "cc/resources/shared_bitmap_id_registrar.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/config/gpu_feature_info.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types_3d.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gpu_preference.h"
namespace cc {
class Layer;
}
namespace gfx {
class GpuMemoryBuffer;
}
namespace gpu {
namespace gles2 {
class GLES2Interface;
}
} // namespace gpu
namespace blink {
class CanvasResource;
class CanvasResourceProvider;
class Extensions3DUtil;
class StaticBitmapImage;
class WebGraphicsContext3DProvider;
class WebGraphicsContext3DProviderWrapper;
// Manages a rendering target (framebuffer + attachment) for a canvas. Can
// publish its rendering results to a cc::Layer for compositing.
class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
public RefCounted<DrawingBuffer> {
public:
class Client {
public:
// Returns true if the DrawingBuffer is currently bound for draw.
virtual bool DrawingBufferClientIsBoundForDraw() = 0;
virtual void DrawingBufferClientRestoreScissorTest() = 0;
// Restores the mask and clear value for color, depth, and stencil buffers.
virtual void DrawingBufferClientRestoreMaskAndClearValues() = 0;
// Assume client knows the GL/WebGL version and restore necessary params
// accordingly.
virtual void DrawingBufferClientRestorePixelPackParameters() = 0;
// Restores the GL_TEXTURE_2D binding for the active texture unit only.
virtual void DrawingBufferClientRestoreTexture2DBinding() = 0;
// Restores the GL_TEXTURE_CUBE_MAP binding for the active texture unit.
virtual void DrawingBufferClientRestoreTextureCubeMapBinding() = 0;
virtual void DrawingBufferClientRestoreRenderbufferBinding() = 0;
virtual void DrawingBufferClientRestoreFramebufferBinding() = 0;
virtual void DrawingBufferClientRestorePixelUnpackBufferBinding() = 0;
virtual void DrawingBufferClientRestorePixelPackBufferBinding() = 0;
virtual bool
DrawingBufferClientUserAllocatedMultisampledRenderbuffers() = 0;
virtual void DrawingBufferClientForceLostContextWithAutoRecovery() = 0;
};
enum PreserveDrawingBuffer {
kPreserve,
kDiscard,
};
enum WebGLVersion {
kWebGL1,
kWebGL2,
};
enum ChromiumImageUsage {
kAllowChromiumImage,
kDisallowChromiumImage,
};
static scoped_refptr<DrawingBuffer> Create(
std::unique_ptr<WebGraphicsContext3DProvider>,
const Platform::GraphicsInfo& graphics_info,
bool using_swap_chain,
Client*,
const gfx::Size&,
bool premultiplied_alpha,
bool want_alpha_channel,
bool want_depth_buffer,
bool want_stencil_buffer,
bool want_antialiasing,
bool desynchronized,
PreserveDrawingBuffer,
WebGLVersion,
ChromiumImageUsage,
cc::PaintFlags::FilterQuality,
PredefinedColorSpace color_space,
CanvasPixelFormat pixel_format,
gl::GpuPreference);
DrawingBuffer(const DrawingBuffer&) = delete;
DrawingBuffer& operator=(const DrawingBuffer&) = delete;
~DrawingBuffer() override;
// Destruction will be completed after all mailboxes are released.
void BeginDestruction();
// Issues a glClear() on all framebuffers associated with this DrawingBuffer.
void ClearFramebuffers(GLbitfield clear_mask);
// Indicates whether the DrawingBuffer internally allocated a packed
// depth-stencil renderbuffer in the situation where the end user only asked
// for a depth buffer. In this case, we need to upgrade clears of the depth
// buffer to clears of the depth and stencil buffers in order to avoid
// performance problems on some GPUs.
bool HasImplicitStencilBuffer() const { return has_implicit_stencil_buffer_; }
bool HasDepthBuffer() const { return !!depth_stencil_buffer_; }
bool HasStencilBuffer() const { return !!depth_stencil_buffer_; }
bool IsUsingGpuCompositing() const {
return graphics_info_.using_gpu_compositing;
}
const Platform::GraphicsInfo& GetGraphicsInfo() const {
return graphics_info_;
}
// Given the desired buffer size, provides the largest dimensions that will
// fit in the pixel budget.
static gfx::Size AdjustSize(const gfx::Size& desired_size,
const gfx::Size& cur_size,
int max_texture_size);
// Resizes (or allocates if necessary) all buffers attached to the default
// framebuffer. Returns whether the operation was successful.
bool Resize(const gfx::Size&);
// Set the color space of the default draw buffer. This will destroy the
// contents of the drawing buffer.
void SetColorSpace(PredefinedColorSpace color_space);
// Bind the default framebuffer to |target|. |target| must be
// GL_FRAMEBUFFER, GL_READ_FRAMEBUFFER, or GL_DRAW_FRAMEBUFFER.
void Bind(GLenum target);
gfx::Size Size() const { return size_; }
GLenum StorageFormat() const;
// Resolves the multisample color buffer to the normal color buffer and leaves
// the resolved color buffer bound to GL_READ_FRAMEBUFFER and
// GL_DRAW_FRAMEBUFFER.
//
// Note that in rare situations on macOS the drawing buffer can be destroyed
// during the resolve process, specifically during automatic graphics
// switching. In this scenario this method returns false.
bool ResolveAndBindForReadAndDraw();
bool Multisample() const;
bool DiscardFramebufferSupported() const {
return discard_framebuffer_supported_;
}
// Returns false if the contents had previously been marked as changed and
// have not yet been resolved.
bool MarkContentsChanged();
void SetBufferClearNeeded(bool);
bool BufferClearNeeded() const;
void SetIsInHiddenPage(bool);
void SetFilterQuality(cc::PaintFlags::FilterQuality);
cc::PaintFlags::FilterQuality FilterQuality() const {
return filter_quality_;
}
// Whether the target for draw operations has format GL_RGBA, but is
// emulating format GL_RGB. When the target's storage is first
// allocated, its alpha channel must be cleared to 1. All future drawing
// operations must use a color mask with alpha=GL_FALSE.
bool RequiresAlphaChannelToBePreserved();
// Similar to requiresAlphaChannelToBePreserved(), but always targets the
// default framebuffer.
bool DefaultBufferRequiresAlphaChannelToBePreserved();
// Set the current GL draw buffer being used with this framebuffer. Allows
// DrawingBuffer to properly reset the draw buffer state when doing internal
// operations.
void SetDrawBuffer(GLenum draw_buffer);
cc::Layer* CcLayer();
gpu::gles2::GLES2Interface* ContextGL();
WebGraphicsContext3DProvider* ContextProvider();
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWeakPtr();
Client* client() { return client_; }
WebGLVersion webgl_version() const { return webgl_version_; }
bool destroyed() const { return destruction_in_progress_; }
// cc::TextureLayerClient implementation.
bool PrepareTransferableResource(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback) override;
// Returns a StaticBitmapImage backed by a texture containing the current
// contents of the front buffer. This is done without any pixel copies. The
// texture in the ImageBitmap is from the active ContextProvider on the
// DrawingBuffer.
scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();
// Returns a UnacceleratedStaticBitmapImage backed by a bitmap that will have
// a copy of the contents of the front buffer. This is only meant to be used
// for unaccelerated canvases as for accelerated contexts there are better
// ways to get a copy of the internal contents.
scoped_refptr<StaticBitmapImage> GetUnacceleratedStaticBitmapImage(
bool flip_y = false);
bool CopyToPlatformTexture(gpu::gles2::GLES2Interface*,
GLenum dst_target,
GLuint dst_texture,
GLint dst_level,
bool premultiply_alpha,
bool flip_y,
const gfx::Point& dst_texture_offset,
const gfx::Rect& src_sub_rectangle,
SourceDrawingBuffer);
bool CopyToPlatformMailbox(gpu::raster::RasterInterface*,
gpu::Mailbox dst_mailbox,
GLenum dst_texture_target,
bool flip_y,
const gfx::Point& dst_texture_offset,
const gfx::Rect& src_sub_rectangle,
SourceDrawingBuffer src_buffer);
bool CopyToVideoFrame(
WebGraphicsContext3DVideoFramePool* frame_pool,
SourceDrawingBuffer src_buffer,
bool src_origin_is_top_left,
const gfx::ColorSpace& dst_color_space,
WebGraphicsContext3DVideoFramePool::FrameReadyCallback callback);
sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer);
int SampleCount() const { return sample_count_; }
bool ExplicitResolveOfMultisampleData() const {
return anti_aliasing_mode_ == kAntialiasingModeMSAAExplicitResolve;
}
// Rebind the read and draw framebuffers that WebGL is expecting.
void RestoreFramebufferBindings();
// Restore all state that may have been dirtied by any call.
void RestoreAllState();
bool UsingSwapChain() const { return using_swap_chain_; }
// Keep track of low latency buffer status.
bool low_latency_enabled() const { return low_latency_enabled_; }
void set_low_latency_enabled(bool low_latency_enabled) {
low_latency_enabled_ = low_latency_enabled;
}
// This class helps implement correct semantics for BlitFramebuffer
// when the DrawingBuffer is using a CHROMIUM image for its backing
// store and RGB emulation is in use (basically, macOS only).
class PLATFORM_EXPORT ScopedRGBEmulationForBlitFramebuffer {
STACK_ALLOCATED();
public:
ScopedRGBEmulationForBlitFramebuffer(DrawingBuffer*,
bool is_user_draw_framebuffer_bound);
~ScopedRGBEmulationForBlitFramebuffer();
private:
scoped_refptr<DrawingBuffer> drawing_buffer_;
bool doing_work_ = false;
};
scoped_refptr<CanvasResource> ExportCanvasResource();
scoped_refptr<CanvasResource> ExportLowLatencyCanvasResource(
base::WeakPtr<CanvasResourceProvider> resource_provider);
static const size_t kDefaultColorBufferCacheLimit;
protected: // For unittests
DrawingBuffer(std::unique_ptr<WebGraphicsContext3DProvider>,
const Platform::GraphicsInfo& graphics_info,
bool using_swap_chain,
bool desynchronized,
std::unique_ptr<Extensions3DUtil>,
Client*,
bool discard_framebuffer_supported,
bool want_alpha_channel,
bool premultiplied_alpha,
PreserveDrawingBuffer,
WebGLVersion,
bool wants_depth,
bool wants_stencil,
ChromiumImageUsage,
cc::PaintFlags::FilterQuality,
PredefinedColorSpace color_space,
CanvasPixelFormat pixel_format,
gl::GpuPreference gpu_preference);
bool Initialize(const gfx::Size&, bool use_multisampling);
struct RegisteredBitmap {
RegisteredBitmap(scoped_refptr<cc::CrossThreadSharedBitmap> bitmap,
cc::SharedBitmapIdRegistration registration)
: bitmap(std::move(bitmap)), registration(std::move(registration)) {}
// Explicitly move-only.
RegisteredBitmap(RegisteredBitmap&&) = default;
RegisteredBitmap& operator=(RegisteredBitmap&&) = default;
scoped_refptr<cc::CrossThreadSharedBitmap> bitmap;
cc::SharedBitmapIdRegistration registration;
};
// Shared memory bitmaps that were released by the compositor and can be used
// again by this DrawingBuffer.
Vector<RegisteredBitmap> recycled_bitmaps_;
private:
friend class ScopedRGBEmulationForBlitFramebuffer;
friend class ScopedStateRestorer;
friend class ColorBuffer;
// This structure should wrap all public entrypoints that may modify GL state.
// It will restore all state when it drops out of scope.
class ScopedStateRestorer {
USING_FAST_MALLOC(ScopedStateRestorer);
public:
ScopedStateRestorer(DrawingBuffer*);
~ScopedStateRestorer();
// Mark parts of the state that are dirty and need to be restored.
void SetClearStateDirty() { clear_state_dirty_ = true; }
void SetPixelPackParametersDirty() { pixel_pack_parameters_dirty_ = true; }
void SetTextureBindingDirty() { texture_binding_dirty_ = true; }
void SetRenderbufferBindingDirty() { renderbuffer_binding_dirty_ = true; }
void SetFramebufferBindingDirty() { framebuffer_binding_dirty_ = true; }
void SetPixelUnpackBufferBindingDirty() {
pixel_unpack_buffer_binding_dirty_ = true;
}
void SetPixelPackBufferBindingDirty() {
pixel_pack_buffer_binding_dirty_ = true;
}
private:
scoped_refptr<DrawingBuffer> drawing_buffer_;
// The previous state restorer, in case restorers are nested.
ScopedStateRestorer* previous_state_restorer_ = nullptr;
bool clear_state_dirty_ = false;
bool pixel_pack_parameters_dirty_ = false;
bool texture_binding_dirty_ = false;
bool renderbuffer_binding_dirty_ = false;
bool framebuffer_binding_dirty_ = false;
bool pixel_unpack_buffer_binding_dirty_ = false;
bool pixel_pack_buffer_binding_dirty_ = false;
};
struct ColorBuffer : public base::RefCountedThreadSafe<ColorBuffer> {
ColorBuffer(base::WeakPtr<DrawingBuffer> drawing_buffer,
const gfx::Size&,
const gfx::ColorSpace& color_space,
viz::ResourceFormat,
GLuint texture_id,
std::unique_ptr<gfx::GpuMemoryBuffer>,
gpu::Mailbox mailbox);
ColorBuffer(const ColorBuffer&) = delete;
ColorBuffer& operator=(const ColorBuffer&) = delete;
~ColorBuffer();
// The thread on which the ColorBuffer is created and the DrawingBuffer is
// bound to.
const base::PlatformThreadRef owning_thread_ref;
// The owning DrawingBuffer. Note that DrawingBuffer is explicitly destroyed
// by the beginDestruction method, which will eventually drain all of its
// ColorBuffers.
base::WeakPtr<DrawingBuffer> drawing_buffer;
const gfx::Size size;
const gfx::ColorSpace color_space;
const viz::ResourceFormat format;
const GLuint texture_id = 0;
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
// If we're emulating an RGB back buffer using an RGBA Chromium
// image (essentially macOS only), then when performing
// BlitFramebuffer calls, we have to swap in an RGB texture in
// place of the RGBA texture bound to the image. The reason is
// that BlitFramebuffer requires the internal formats of the
// source and destination to match (e.g. RGB8 on both sides).
// There are bugs in the semantics of RGB8 textures in this
// situation (the alpha channel is zeroed), requiring more fixups.
GLuint rgb_workaround_texture_id = 0;
// The mailbox used to send this buffer to the compositor.
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;
};
using CopyFunctionRef = base::FunctionRef<bool(const gpu::MailboxHolder&,
viz::ResourceFormat,
const gfx::Size&,
const gfx::ColorSpace&)>;
bool CopyToPlatformInternal(gpu::InterfaceBase* dst_interface,
SourceDrawingBuffer src_buffer,
CopyFunctionRef copy_function);
enum ClearOption { kClearOnlyMultisampledFBO, kClearAllFBOs };
// Clears out newly-allocated framebuffers (really, renderbuffers / textures).
void ClearNewlyAllocatedFramebuffers(ClearOption clear_option);
// The same as clearFramebuffers(), but leaves GL state dirty.
void ClearFramebuffersInternal(GLbitfield clear_mask,
ClearOption clear_option);
// The same as reset(), but leaves GL state dirty.
bool ResizeFramebufferInternal(const gfx::Size&);
// The same as resolveAndBindForReadAndDraw(), but leaves GL state dirty.
void ResolveMultisampleFramebufferInternal();
// Resolves m_multisampleFBO into m_fbo, if multisampling.
void ResolveIfNeeded();
enum CheckForDestructionResult {
kDestroyedOrLost,
kContentsUnchanged,
kContentsResolvedIfNeeded
};
// This method:
// - Checks if the context or the resource has been destroyed
// - Checks whether there are changes in the content
// - Checks whether the context has been lost
// If all of the above checks pass, resolves the multisampled
// renderbuffer if needed.
CheckForDestructionResult CheckForDestructionAndChangeAndResolveIfNeeded();
bool PrepareTransferableResourceInternal(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback,
bool force_gpu_result);
// Helper functions to be called only by PrepareTransferableResourceInternal.
bool FinishPrepareTransferableResourceGpu(
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback);
bool FinishPrepareTransferableResourceSoftware(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback);
// Callbacks for mailboxes given to the compositor from
// FinishPrepareTransferableResource{Gpu,Software}.
static void NotifyMailboxReleasedGpu(scoped_refptr<ColorBuffer>,
const gpu::SyncToken&,
bool lost_resource);
void MailboxReleasedGpu(scoped_refptr<ColorBuffer>, bool lost_resource);
void MailboxReleasedSoftware(RegisteredBitmap,
const gpu::SyncToken&,
bool lost_resource);
// Reallocates the storage for all buffers. This is called due to a change in
// the properties of the buffer (e.g, its size or color space). If
// `only_reallocate_color` is true, then do not reallocate the depth stencil
// buffer.
bool ReallocateDefaultFramebuffer(const gfx::Size&,
bool only_reallocate_color);
void ClearCcLayer();
RegisteredBitmap CreateOrRecycleBitmap(
cc::SharedBitmapIdRegistrar* bitmap_registrar);
// Updates the current size of the buffer, ensuring that
// s_currentResourceUsePixels is updated.
void SetSize(const gfx::Size&);
// Read the content of the FrameBuffer into the bitmap.
void ReadFramebufferIntoBitmapPixels(uint8_t* pixels);
// Helper function which does a readback from the currently-bound
// framebuffer into a buffer of a certain size with 4-byte pixels.
void ReadBackFramebuffer(base::span<uint8_t> pixels,
SkColorType,
WebGLImageConversion::AlphaOp);
// If RGB emulation is required, then the CHROMIUM image's alpha channel
// must be immediately cleared after it is bound to a texture. Nothing
// should be allowed to change the alpha channel after this.
void ClearChromiumImageAlpha(const ColorBuffer&);
// Tries to create a CHROMIUM_image backed texture if
// RuntimeEnabledFeatures::WebGLImageChromiumEnabled() is true. On failure,
// or if the flag is false, creates a default texture. Always returns a valid
// ColorBuffer.
scoped_refptr<ColorBuffer> CreateColorBuffer(const gfx::Size&);
// Creates or recycles a ColorBuffer of size |m_size|.
scoped_refptr<ColorBuffer> CreateOrRecycleColorBuffer();
// Attaches |m_backColorBuffer| to |m_fbo|, which is always the source for
// read operations.
void AttachColorBufferToReadFramebuffer();
// Whether the WebGL client desires an explicit resolve. This is
// implemented by forwarding all draw operations to a multisample
// renderbuffer, which is resolved before any read operations or swaps.
bool WantExplicitResolve();
// Whether the WebGL client wants a depth or stencil buffer.
bool WantDepthOrStencil();
// Helpers to ensure correct behavior of BlitFramebuffer when using
// an emulated RGB CHROMIUM_image back buffer.
bool SetupRGBEmulationForBlitFramebuffer(bool is_user_draw_framebuffer_bound);
void CleanupRGBEmulationForBlitFramebuffer();
// Reallocate Multisampled renderbuffer, used by explicit resolve when resize
// and GPU switch
bool ReallocateMultisampleRenderbuffer(const gfx::Size&);
// Presents swap chain if swap chain is being used and contents have changed.
void ResolveAndPresentSwapChainIfNeeded();
// Weak, reset by beginDestruction.
Client* client_ = nullptr;
const PreserveDrawingBuffer preserve_drawing_buffer_;
const WebGLVersion webgl_version_;
std::unique_ptr<WebGraphicsContext3DProviderWrapper> context_provider_;
// Lifetime is tied to the m_contextProvider.
gpu::gles2::GLES2Interface* gl_;
std::unique_ptr<Extensions3DUtil> extensions_util_;
gfx::Size size_;
const bool discard_framebuffer_supported_;
// Did the user request an alpha channel be allocated.
const bool want_alpha_channel_;
// Does our allocation have an alpha channel that was explicitly allocated
// (there is no concept of an implicitly created alpha channel). This
// determines if |multisample_renderbuffer_| allocates an alpha channel.
bool have_alpha_channel_ = false;
const bool premultiplied_alpha_;
Platform::GraphicsInfo graphics_info_;
const bool using_swap_chain_;
bool low_latency_enabled_ = false;
bool has_implicit_stencil_buffer_ = false;
// The texture target (2D or RECTANGLE) for our allocations.
GLenum texture_target_ = 0;
// The current state restorer, which is used to track state dirtying. It is an
// error to dirty state shared with WebGL while there is no existing state
// restorer.
ScopedStateRestorer* state_restorer_ = nullptr;
// This is used when the user requests either a depth or stencil buffer.
GLuint depth_stencil_buffer_ = 0;
// When wantExplicitResolve() returns true, the target of all draw
// operations.
GLuint multisample_fbo_ = 0;
// The id of the renderbuffer storage for |m_multisampleFBO|.
GLuint multisample_renderbuffer_ = 0;
// If premultipliedAlpha:false is set during context creation, and a
// GpuMemoryBuffer is used for the DrawingBuffer's storage, then a separate,
// regular, OpenGL texture is allocated to hold either the rendering results
// (if antialias:false) or resolve results (if antialias:true). Then
// CopyTextureCHROMIUM is used to multiply the alpha channel into the color
// channels when copying into the GMB.
GLuint premultiplied_alpha_false_texture_ = 0;
// A mailbox for the premultiplied_alpha_false_texture_, created lazily if we
// need to produce it.
gpu::Mailbox premultiplied_alpha_false_mailbox_;
// When wantExplicitResolve() returns false, the target of all draw and
// read operations. When wantExplicitResolve() returns true, the target of
// all read operations.
GLuint fbo_ = 0;
// The ColorBuffer that backs |m_fbo|.
scoped_refptr<ColorBuffer> back_color_buffer_;
// The ColorBuffer that was most recently presented to the compositor by
// PrepareTransferableResourceInternal.
scoped_refptr<ColorBuffer> front_color_buffer_;
// True if our contents have been modified since the last presentation of this
// buffer.
bool contents_changed_ = true;
// True if resolveIfNeeded() has been called since the last time
// markContentsChanged() had been called.
bool contents_change_resolved_ = false;
bool buffer_clear_needed_ = false;
// Whether the client wants a depth or stencil buffer.
const bool want_depth_;
const bool want_stencil_;
// The color space of this buffer.
gfx::ColorSpace color_space_;
AntialiasingMode anti_aliasing_mode_ = kAntialiasingModeNone;
bool use_half_float_storage_ = false;
int max_texture_size_ = 0;
int sample_count_ = 0;
int eqaa_storage_sample_count_ = 0;
bool destruction_in_progress_ = false;
bool is_hidden_ = false;
bool has_eqaa_support = false;
cc::PaintFlags::FilterQuality filter_quality_ =
cc::PaintFlags::FilterQuality::kLow;
GLenum draw_buffer_ = GL_COLOR_ATTACHMENT0;
scoped_refptr<cc::TextureLayer> layer_;
// Mailboxes that were released by the compositor can be used again by this
// DrawingBuffer.
Deque<scoped_refptr<ColorBuffer>> recycled_color_buffer_queue_;
// In the case of OffscreenCanvas, we do not want to enable the
// WebGLImageChromium flag, so we replace all the
// RuntimeEnabledFeatures::WebGLImageChromiumEnabled() call with
// shouldUseChromiumImage() calls, and set m_chromiumImageUsage to
// DisallowChromiumImage in the case of OffscreenCanvas.
ChromiumImageUsage chromium_image_usage_;
bool ShouldUseChromiumImage();
bool opengl_flip_y_extension_;
const gl::GpuPreference initial_gpu_;
gl::GpuPreference current_active_gpu_;
base::WeakPtrFactory<DrawingBuffer> weak_factory_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DRAWING_BUFFER_H_