#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include <algorithm>
#include <memory>
#include <utility>
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/ostream_operators.h"
#include "build/build_config.h"
#include "cc/layers/texture_layer.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/common/resources/shared_bitmap.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_finch_features.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_shared_image_interface_provider.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "v8/include/v8.h"
namespace blink {
namespace {
BASE_FEATURE(…);
const float kResourceAdjustedRatio = …;
bool g_should_fail_drawing_buffer_creation_for_testing = …;
void FlipVertically(base::span<uint8_t> framebuffer,
size_t num_rows,
size_t row_bytes) { … }
class ScopedDrawBuffer { … };
}
#if BUILDFLAG(IS_FUCHSIA)
const size_t DrawingBuffer::kDefaultColorBufferCacheLimit = 2;
#else
const size_t DrawingBuffer::kDefaultColorBufferCacheLimit = …;
#endif
void ForceNextDrawingBufferCreationToFailForTest() { … }
scoped_refptr<DrawingBuffer> DrawingBuffer::Create(
std::unique_ptr<WebGraphicsContext3DProvider> context_provider,
const Platform::GraphicsInfo& graphics_info,
bool using_swap_chain,
Client* client,
const gfx::Size& size,
bool premultiplied_alpha,
bool want_alpha_channel,
bool want_depth_buffer,
bool want_stencil_buffer,
bool want_antialiasing,
bool desynchronized,
PreserveDrawingBuffer preserve,
WebGLVersion webgl_version,
ChromiumImageUsage chromium_image_usage,
cc::PaintFlags::FilterQuality filter_quality,
PredefinedColorSpace color_space,
gl::GpuPreference gpu_preference) { … }
DrawingBuffer::DrawingBuffer(
std::unique_ptr<WebGraphicsContext3DProvider> context_provider,
const Platform::GraphicsInfo& graphics_info,
bool using_swap_chain,
bool desynchronized,
std::unique_ptr<Extensions3DUtil> extensions_util,
Client* client,
bool discard_framebuffer_supported,
bool texture_storage_enabled,
bool want_alpha_channel,
bool premultiplied_alpha,
PreserveDrawingBuffer preserve,
WebGLVersion webgl_version,
bool want_depth,
bool want_stencil,
ChromiumImageUsage chromium_image_usage,
cc::PaintFlags::FilterQuality filter_quality,
PredefinedColorSpace color_space,
gl::GpuPreference gpu_preference)
: … { … }
DrawingBuffer::~DrawingBuffer() { … }
bool DrawingBuffer::MarkContentsChanged() { … }
bool DrawingBuffer::BufferClearNeeded() const { … }
void DrawingBuffer::SetBufferClearNeeded(bool flag) { … }
gpu::gles2::GLES2Interface* DrawingBuffer::ContextGL() { … }
WebGraphicsContext3DProvider* DrawingBuffer::ContextProvider() { … }
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
DrawingBuffer::ContextProviderWeakPtr() { … }
void DrawingBuffer::SetIsInHiddenPage(bool hidden) { … }
void DrawingBuffer::SetHdrMetadata(const gfx::HDRMetadata& hdr_metadata) { … }
void DrawingBuffer::SetFilterQuality(
cc::PaintFlags::FilterQuality filter_quality) { … }
bool DrawingBuffer::RequiresAlphaChannelToBePreserved() { … }
bool DrawingBuffer::DefaultBufferRequiresAlphaChannelToBePreserved() { … }
void DrawingBuffer::SetDrawBuffer(GLenum draw_buffer) { … }
void DrawingBuffer::SetSharedImageInterfaceProviderForBitmapTest(
std::unique_ptr<WebGraphicsSharedImageInterfaceProvider> sii_provider) { … }
WebGraphicsSharedImageInterfaceProvider*
DrawingBuffer::GetSharedImageInterfaceProviderForBitmap() { … }
DrawingBuffer::RegisteredBitmap DrawingBuffer::CreateOrRecycleBitmap(
cc::SharedBitmapIdRegistrar* bitmap_registrar) { … }
bool DrawingBuffer::PrepareTransferableResource(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback) { … }
DrawingBuffer::CheckForDestructionResult
DrawingBuffer::CheckForDestructionAndChangeAndResolveIfNeeded(
DiscardBehavior discardBehavior) { … }
bool DrawingBuffer::PrepareTransferableResourceInternal(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
scoped_refptr<gpu::ClientSharedImage>* client_si,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback,
bool force_gpu_result) { … }
scoped_refptr<StaticBitmapImage>
DrawingBuffer::GetUnacceleratedStaticBitmapImage(bool flip_y) { … }
void DrawingBuffer::ReadFramebufferIntoBitmapPixels(uint8_t* pixels) { … }
bool DrawingBuffer::FinishPrepareTransferableResourceSoftware(
cc::SharedBitmapIdRegistrar* bitmap_registrar,
viz::TransferableResource* out_resource,
viz::ReleaseCallback* out_release_callback) { … }
bool DrawingBuffer::FinishPrepareTransferableResourceGpu(
viz::TransferableResource* out_resource,
scoped_refptr<gpu::ClientSharedImage>* client_si,
viz::ReleaseCallback* out_release_callback) { … }
void DrawingBuffer::NotifyMailboxReleasedGpu(
scoped_refptr<ColorBuffer> color_buffer,
const gpu::SyncToken& sync_token,
bool lost_resource) { … }
void DrawingBuffer::MailboxReleasedGpu(scoped_refptr<ColorBuffer> color_buffer,
bool lost_resource) { … }
void DrawingBuffer::MailboxReleasedSoftware(RegisteredBitmap registered,
const gpu::SyncToken& sync_token,
bool lost_resource) { … }
scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage() { … }
scoped_refptr<DrawingBuffer::ColorBuffer>
DrawingBuffer::CreateOrRecycleColorBuffer() { … }
scoped_refptr<CanvasResource> DrawingBuffer::ExportLowLatencyCanvasResource(
base::WeakPtr<CanvasResourceProvider> resource_provider) { … }
scoped_refptr<CanvasResource> DrawingBuffer::ExportCanvasResource() { … }
DrawingBuffer::ColorBuffer::ColorBuffer(
base::WeakPtr<DrawingBuffer> drawing_buffer,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
viz::SharedImageFormat format,
SkAlphaType alpha_type,
GLenum texture_target,
GLuint texture_id,
bool is_overlay_candidate,
scoped_refptr<gpu::ClientSharedImage> shared_image)
: … { … }
DrawingBuffer::ColorBuffer::~ColorBuffer() { … }
bool DrawingBuffer::Initialize(const gfx::Size& size, bool use_multisampling) { … }
void DrawingBuffer::CopyStagingTextureToBackColorBufferIfNeeded() { … }
bool DrawingBuffer::CopyToPlatformInternal(gpu::InterfaceBase* dst_interface,
bool dst_is_unpremul_gl,
SourceDrawingBuffer src_buffer,
CopyFunctionRef copy_function) { … }
bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
GLenum dst_texture_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 src_buffer) { … }
bool DrawingBuffer::CopyToPlatformMailbox(
gpu::raster::RasterInterface* dst_raster_interface,
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 DrawingBuffer::CopyToVideoFrame(
WebGraphicsContext3DVideoFramePool* frame_pool,
SourceDrawingBuffer src_buffer,
bool src_origin_is_top_left,
const gfx::ColorSpace& dst_color_space,
WebGraphicsContext3DVideoFramePool::FrameReadyCallback callback) { … }
cc::Layer* DrawingBuffer::CcLayer() { … }
void DrawingBuffer::ClearCcLayer() { … }
void DrawingBuffer::BeginDestruction() { … }
bool DrawingBuffer::ReallocateDefaultFramebuffer(const gfx::Size& size,
bool only_reallocate_color) { … }
void DrawingBuffer::ClearFramebuffers(GLbitfield clear_mask) { … }
void DrawingBuffer::ClearFramebuffersInternal(GLbitfield clear_mask,
ClearOption clear_option) { … }
void DrawingBuffer::ClearNewlyAllocatedFramebuffers(ClearOption clear_option) { … }
gfx::Size DrawingBuffer::AdjustSize(const gfx::Size& desired_size,
const gfx::Size& cur_size,
int max_texture_size) { … }
bool DrawingBuffer::Resize(const gfx::Size& new_size) { … }
bool DrawingBuffer::ResizeWithFormat(GLenum requested_format,
SkAlphaType requested_alpha_type,
const gfx::Size& new_size) { … }
bool DrawingBuffer::ResizeFramebufferInternal(GLenum requested_format,
SkAlphaType requested_alpha_type,
const gfx::Size& new_size) { … }
void DrawingBuffer::SetColorSpace(PredefinedColorSpace predefined_color_space) { … }
bool DrawingBuffer::ResolveAndBindForReadAndDraw() { … }
void DrawingBuffer::ResolveMultisampleFramebufferInternal() { … }
void DrawingBuffer::ResolveIfNeeded(DiscardBehavior discardBehavior) { … }
bool DrawingBuffer::ReallocateMultisampleRenderbuffer(const gfx::Size& size) { … }
void DrawingBuffer::RestoreFramebufferBindings() { … }
void DrawingBuffer::RestoreAllState() { … }
bool DrawingBuffer::Multisample() const { … }
void DrawingBuffer::Bind(GLenum target) { … }
GLenum DrawingBuffer::StorageFormat() const { … }
sk_sp<SkData> DrawingBuffer::PaintRenderingResultsToDataArray(
SourceDrawingBuffer source_buffer) { … }
void DrawingBuffer::ReadBackFramebuffer(base::span<uint8_t> pixels,
SkColorType color_type,
WebGLImageConversion::AlphaOp op) { … }
void DrawingBuffer::ResolveAndPresentSwapChainIfNeeded() { … }
scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
const gfx::Size& size) { … }
void DrawingBuffer::AttachColorBufferToReadFramebuffer() { … }
bool DrawingBuffer::WantExplicitResolve() { … }
bool DrawingBuffer::WantDepthOrStencil() { … }
DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer(
DrawingBuffer* drawing_buffer)
: … { … }
DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { … }
bool DrawingBuffer::ShouldUseChromiumImage() { … }
}