| // Copyright 2018 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef GPU_COMMAND_BUFFER_CLIENT_RASTER_IMPLEMENTATION_H_ | |
| #define GPU_COMMAND_BUFFER_CLIENT_RASTER_IMPLEMENTATION_H_ | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "base/containers/span.h" | |
| #include "base/feature.h" | |
| #include "base/memory/raw_ptr.h" | |
| #include "base/trace_event/memory_dump_provider.h" | |
| #include "cc/paint/paint_cache.h" | |
| #include "cc/paint/skottie_serialization_history.h" | |
| #include "gpu/command_buffer/client/client_font_manager.h" | |
| #include "gpu/command_buffer/client/context_support.h" | |
| #include "gpu/command_buffer/client/gpu_control_client.h" | |
| #include "gpu/command_buffer/client/implementation_base.h" | |
| #include "gpu/command_buffer/client/logging.h" | |
| #include "gpu/command_buffer/client/mapped_memory.h" | |
| #include "gpu/command_buffer/client/raster_interface.h" | |
| #include "gpu/command_buffer/client/transfer_buffer.h" | |
| #include "gpu/command_buffer/common/context_result.h" | |
| #include "gpu/command_buffer/common/debug_marker_manager.h" | |
| #include "gpu/command_buffer/common/discardable_handle.h" | |
| #include "gpu/command_buffer/common/id_allocator.h" | |
| #include "gpu/command_buffer/common/raster_cmd_format.h" | |
| #include "gpu/raster_export.h" | |
| namespace cc { | |
| class TransferCacheSerializeHelper; | |
| } // namespace cc | |
| namespace gpu { | |
| class GpuControl; | |
| struct SharedMemoryLimits; | |
| namespace raster { | |
| class RasterCmdHelper; | |
| RASTER_EXPORT BASE_DECLARE_FEATURE(kDisableErrorHandlingForReadback); | |
| // This class emulates Raster over command buffers. It can be used by a client | |
| // program so that the program does not need deal with shared memory and command | |
| // buffer management. | |
| class RASTER_EXPORT RasterImplementation : public RasterInterface, | |
| public ImplementationBase, | |
| public ClientTransferCache::Client, | |
| public gles2::QueryTrackerClient, | |
| public ClientFontManager::Client { | |
| public: | |
| RasterImplementation(RasterCmdHelper* helper, | |
| TransferBufferInterface* transfer_buffer, | |
| bool lose_context_when_out_of_memory, | |
| GpuControl* gpu_control); | |
| RasterImplementation(const RasterImplementation&) = delete; | |
| RasterImplementation& operator=(const RasterImplementation&) = delete; | |
| ~RasterImplementation() override; | |
| gpu::ContextResult Initialize(const SharedMemoryLimits& limits); | |
| // The RasterCmdHelper being used by this RasterImplementation. You can use | |
| // this to issue cmds at a lower level for certain kinds of optimization. | |
| RasterCmdHelper* helper() const; | |
| // QueryTrackerClient implementation. | |
| void IssueBeginQuery(GLenum target, | |
| GLuint id, | |
| uint32_t sync_data_shm_id, | |
| uint32_t sync_data_shm_offset) override; | |
| void IssueEndQuery(GLenum target, GLuint submit_count) override; | |
| void IssueQueryCounter(GLuint id, | |
| GLenum target, | |
| uint32_t sync_data_shm_id, | |
| uint32_t sync_data_shm_offset, | |
| GLuint submit_count) override; | |
| void IssueSetDisjointValueSync(uint32_t sync_data_shm_id, | |
| uint32_t sync_data_shm_offset) override; | |
| GLenum GetClientSideGLError() override; | |
| CommandBufferHelper* cmd_buffer_helper() override; | |
| void SetGLError(GLenum error, | |
| const char* function_name, | |
| const char* msg) override; | |
| // ClientTransferCache::Client implementation. | |
| void IssueCreateTransferCacheEntry(GLuint entry_type, | |
| GLuint entry_id, | |
| GLuint handle_shm_id, | |
| GLuint handle_shm_offset, | |
| GLuint data_shm_id, | |
| GLuint data_shm_offset, | |
| GLuint data_size) override; | |
| void IssueDeleteTransferCacheEntry(GLuint entry_type, | |
| GLuint entry_id) override; | |
| void IssueUnlockTransferCacheEntry(GLuint entry_type, | |
| GLuint entry_id) override; | |
| CommandBuffer* command_buffer() const override; | |
| // Include the auto-generated part of this class. We split this because | |
| // it means we can easily edit the non-auto generated parts right here in | |
| // this file instead of having to edit some template or the code generator. | |
| #include "gpu/command_buffer/client/raster_implementation_autogen.h" | |
| // RasterInterface implementation. | |
| const Capabilities& GetCapabilities() const override; | |
| void CopySharedImage(const gpu::Mailbox& source_mailbox, | |
| const gpu::Mailbox& dest_mailbox, | |
| GLint xoffset, | |
| GLint yoffset, | |
| GLint x, | |
| GLint y, | |
| GLsizei width, | |
| GLsizei height) override; | |
| void CopySharedImage(const gpu::Mailbox& source_mailbox, | |
| const gpu::Mailbox& dest_mailbox, | |
| const gfx::Rect& source_rect, | |
| const gfx::Rect& dest_rect) override; | |
| void WritePixels(const gpu::Mailbox& dest_mailbox, | |
| int dst_x_offset, | |
| int dst_y_offset, | |
| GLenum texture_target, | |
| const SkPixmap& src_sk_pixmap) override; | |
| void WritePixelsYUV(const gpu::Mailbox& dest_mailbox, | |
| const SkYUVAPixmaps& src_yuv_pixmap) override; | |
| void BeginRasterCHROMIUM(SkColor4f sk_color_4f, | |
| GLboolean needs_clear, | |
| GLuint msaa_sample_count, | |
| MsaaMode msaa_mode, | |
| GLboolean can_use_lcd_text, | |
| GLboolean visible, | |
| const gfx::ColorSpace& color_space, | |
| float hdr_headroom, | |
| const GLbyte* mailbox) override; | |
| void RasterCHROMIUM(const cc::DisplayItemList* list, | |
| cc::ImageProvider* provider, | |
| const gfx::Size& content_size, | |
| const gfx::Rect& full_raster_rect, | |
| const gfx::Rect& playback_rect, | |
| const gfx::Vector2dF& post_translate, | |
| const gfx::Vector2dF& post_scale, | |
| bool requires_clear, | |
| const ScrollOffsetMap* raster_inducing_scroll_offsets, | |
| size_t* max_op_size_hint, | |
| base::RepeatingCallback<void(SkCanvas*, uint32_t)> | |
| custom_raster_callback) override; | |
| void ReadbackARGBPixelsAsync( | |
| const gpu::Mailbox& source_mailbox, | |
| GLenum source_target, | |
| GrSurfaceOrigin source_origin, | |
| const gfx::Size& source_size, | |
| const gfx::Point& source_starting_point, | |
| const SkImageInfo& dst_info, | |
| GLuint dst_row_bytes, | |
| base::span<uint8_t> out, | |
| base::OnceCallback<void(bool)> readback_done) override; | |
| void ReadbackYUVPixelsAsync( | |
| const gpu::Mailbox& source_mailbox, | |
| GLenum source_target, | |
| const gfx::Rect& source_rect, | |
| const gfx::Rect& output_rect, | |
| bool vertically_flip_texture, | |
| int y_plane_row_stride_bytes, | |
| base::span<uint8_t> y_plane_data, | |
| int u_plane_row_stride_bytes, | |
| base::span<uint8_t> u_plane_data, | |
| int v_plane_row_stride_bytes, | |
| base::span<uint8_t> v_plane_data, | |
| base::OnceCallback<void()> release_mailbox, | |
| base::OnceCallback<void(bool)> readback_done) override; | |
| bool ReadbackImagePixels(const gpu::Mailbox& source_mailbox, | |
| const gfx::Size& source_size, | |
| const SkImageInfo& dst_info, | |
| GLuint dst_row_bytes, | |
| int src_x, | |
| int src_y, | |
| int plane_index, | |
| void* dst_pixels) override; | |
| // ContextSupport implementation. | |
| void SetAggressivelyFreeResources(bool aggressively_free_resources) override; | |
| void SetErrorMessageCallback( | |
| base::RepeatingCallback<void(const char*, int32_t)> callback) override; | |
| base::span<uint8_t> MapTransferCacheEntry(uint32_t serialized_size) override; | |
| void UnmapAndCreateTransferCacheEntry(uint32_t type, uint32_t id) override; | |
| bool ThreadsafeLockTransferCacheEntry(uint32_t type, uint32_t id) override; | |
| void UnlockTransferCacheEntries( | |
| const std::vector<std::pair<uint32_t, uint32_t>>& entries) override; | |
| void DeleteTransferCacheEntry(uint32_t type, uint32_t id) override; | |
| unsigned int GetTransferBufferFreeSize() const override; | |
| // InterfaceBase implementation. | |
| void GenSyncTokenCHROMIUM(GLbyte* sync_token) override; | |
| void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) override; | |
| void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) override; | |
| void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; | |
| void ShallowFlushCHROMIUM() override; | |
| bool GetQueryObjectValueHelper(const char* function_name, | |
| GLuint id, | |
| GLenum pname, | |
| GLuint64* params); | |
| // ClientFontManager::Client implementation. | |
| base::span<uint8_t> MapFontBuffer(uint32_t size) override; | |
| void set_max_inlined_entry_size_for_testing(uint32_t max_size) { | |
| max_inlined_entry_size_ = max_size; | |
| } | |
| std::unique_ptr<cc::TransferCacheSerializeHelper> | |
| CreateTransferCacheHelperForTesting(); | |
| void SetRasterMappedBufferForTesting(ScopedTransferBufferPtr buffer); | |
| private: | |
| class TransferCacheSerializeHelperImpl; | |
| class PaintOpSerializer; | |
| friend class RasterImplementationTest; | |
| using IdNamespaces = raster::id_namespaces::IdNamespaces; | |
| struct TextureUnit { | |
| TextureUnit() : bound_texture_2d(0) {} | |
| // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture | |
| GLuint bound_texture_2d; | |
| }; | |
| // Checks for single threaded access. | |
| class SingleThreadChecker { | |
| public: | |
| explicit SingleThreadChecker(RasterImplementation* raster_implementation); | |
| ~SingleThreadChecker(); | |
| private: | |
| raw_ptr<RasterImplementation> raster_implementation_; | |
| }; | |
| // ImplementationBase implementation. | |
| void IssueShallowFlush() override; | |
| // GpuControlClient implementation. | |
| void OnGpuControlLostContext() final; | |
| void OnGpuControlLostContextMaybeReentrant() final; | |
| void OnGpuControlErrorMessage(const char* message, int32_t id) final; | |
| void OnGpuControlReturnData(base::span<const uint8_t> data) final; | |
| // Gets the GLError through our wrapper. | |
| GLenum GetGLError(); | |
| // Sets our wrapper for the GLError. | |
| void SetGLErrorInvalidEnum(const char* function_name, | |
| GLenum value, | |
| const char* label); | |
| // Try to map a transfer buffer of `size`. Will return a span of up to `size` | |
| // bytes. Returns an empty span on failure. | |
| base::span<uint8_t> MapRasterCHROMIUM(uint32_t size); | |
| // |raster_written_size| is the size of buffer used by raster commands. | |
| // |total_written_size| is the total size of the buffer written to, including | |
| // any transfer cache entries inlined into the buffer. | |
| void UnmapRasterCHROMIUM(uint32_t raster_written_size, | |
| uint32_t total_written_size); | |
| // Returns the last error and clears it. Useful for debugging. | |
| const std::string& GetLastError() { return last_error_; } | |
| void GenQueriesEXTHelper(GLsizei n, const GLuint* queries); | |
| void DeleteTexturesHelper(GLsizei n, const GLuint* textures); | |
| void DeleteQueriesEXTHelper(GLsizei n, const GLuint* queries); | |
| // IdAllocators for objects that can't be shared among contexts. | |
| IdAllocator* GetIdAllocator(IdNamespaces id_namespace); | |
| void FinishHelper(); | |
| void FlushHelper(); | |
| void RunIfContextNotLost(base::OnceClosure callback); | |
| cc::ClientPaintCache* GetOrCreatePaintCache(); | |
| void FlushPaintCachePurgedEntries(); | |
| void ClearPaintCache(); | |
| const std::string& GetLogPrefix() const; | |
| bool ReadbackImagePixelsINTERNAL(const gpu::Mailbox& source_mailbox, | |
| const gfx::Size& source_size, | |
| const SkImageInfo& dst_info, | |
| GLuint dst_row_bytes, | |
| int src_x, | |
| int src_y, | |
| int plane_index, | |
| base::OnceCallback<void(bool)> readback_done, | |
| base::span<uint8_t> dst_pixels); | |
| struct AsyncARGBReadbackRequest; | |
| void OnAsyncARGBReadbackDone(AsyncARGBReadbackRequest* request); | |
| base::queue<std::unique_ptr<AsyncARGBReadbackRequest>> argb_request_queue_; | |
| struct AsyncYUVReadbackRequest; | |
| void OnAsyncYUVReadbackDone(AsyncYUVReadbackRequest* request); | |
| base::queue<std::unique_ptr<AsyncYUVReadbackRequest>> yuv_request_queue_; | |
| void CancelRequests(); | |
| // Set to 1 to have the client fail when a GL error is generated. | |
| // This helps find bugs in the renderer since the debugger stops on the error. | |
| #if DCHECK_IS_ON() | |
| #if 0 | |
| #define RASTER_CLIENT_FAIL_GL_ERRORS | |
| #endif | |
| #endif | |
| #if defined(RASTER_CLIENT_FAIL_GL_ERRORS) | |
| void CheckGLError(); | |
| void FailGLError(GLenum error); | |
| #else | |
| void CheckGLError() {} | |
| void FailGLError(GLenum /* error */) {} | |
| #endif | |
| raw_ptr<RasterCmdHelper> helper_; | |
| std::string last_error_; | |
| gles2::DebugMarkerManager debug_marker_manager_; | |
| std::string this_in_hex_; | |
| // Current GL error bits. | |
| uint32_t error_bits_; | |
| LogSettings log_settings_; | |
| // When true, the context is lost when a GL_OUT_OF_MEMORY error occurs. | |
| const bool lose_context_when_out_of_memory_; | |
| // Used to check for single threaded access. | |
| int use_count_; | |
| std::optional<ScopedMappedMemoryPtr> font_mapped_buffer_; | |
| std::optional<ScopedTransferBufferPtr> raster_mapped_buffer_; | |
| base::RepeatingCallback<void(const char*, int32_t)> error_message_callback_; | |
| int current_trace_stack_; | |
| // Flag to indicate whether the implementation can retain resources, or | |
| // whether it should aggressively free them. | |
| bool aggressively_free_resources_; | |
| IdAllocator query_id_allocator_; | |
| ClientFontManager font_manager_; | |
| mutable base::Lock lost_lock_; | |
| bool lost_ GUARDED_BY(lost_lock_); | |
| // To avoid repeated allocations when searching the rtrees, hold onto this | |
| // vector between RasterCHROMIUM calls. It is not valid outside of that | |
| // function. | |
| std::vector<size_t> temp_raster_offsets_; | |
| struct RasterProperties { | |
| RasterProperties(SkColor4f background_color, | |
| bool can_use_lcd_text, | |
| sk_sp<SkColorSpace> color_space); | |
| ~RasterProperties(); | |
| SkColor4f background_color = SkColors::kWhite; | |
| bool can_use_lcd_text = false; | |
| sk_sp<SkColorSpace> color_space; | |
| }; | |
| std::optional<RasterProperties> raster_properties_; | |
| uint32_t max_inlined_entry_size_; | |
| ClientTransferCache transfer_cache_; | |
| std::string last_active_url_; | |
| cc::ClientPaintCache::PurgedData temp_paint_cache_purged_data_; | |
| std::unique_ptr<cc::ClientPaintCache> paint_cache_; | |
| cc::SkottieSerializationHistory skottie_serialization_history_; | |
| // Tracing helpers. | |
| int raster_chromium_id_ = 0; | |
| }; | |
| } // namespace raster | |
| } // namespace gpu | |
| #endif // GPU_COMMAND_BUFFER_CLIENT_RASTER_IMPLEMENTATION_H_ |