| // Copyright 2012 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_GLES2_IMPLEMENTATION_H_ | |
| #define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_ | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <array> | |
| #include <map> | |
| #include <memory> | |
| #include <optional> | |
| #include <set> | |
| #include <string> | |
| #include <unordered_map> | |
| #include <utility> | |
| #include <vector> | |
| #include "base/compiler_specific.h" | |
| #include "base/containers/heap_array.h" | |
| #include "base/containers/queue.h" | |
| #include "base/containers/span.h" | |
| #include "base/memory/raw_ptr.h" | |
| #include "base/memory/weak_ptr.h" | |
| #include "base/trace_event/memory_dump_provider.h" | |
| #include "gpu/command_buffer/client/buffer_tracker.h" | |
| #include "gpu/command_buffer/client/client_context_state.h" | |
| #include "gpu/command_buffer/client/client_transfer_cache.h" | |
| #include "gpu/command_buffer/client/context_support.h" | |
| #include "gpu/command_buffer/client/gles2_impl_export.h" | |
| #include "gpu/command_buffer/client/gles2_interface.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/query_tracker.h" | |
| #include "gpu/command_buffer/client/readback_buffer_shadow_tracker.h" | |
| #include "gpu/command_buffer/client/ref_counted.h" | |
| #include "gpu/command_buffer/client/share_group.h" | |
| #include "gpu/command_buffer/client/transfer_buffer.h" | |
| #include "gpu/command_buffer/common/context_creation_attribs.h" | |
| #include "gpu/command_buffer/common/context_result.h" | |
| #include "gpu/command_buffer/common/debug_marker_manager.h" | |
| namespace gpu { | |
| class IdAllocator; | |
| namespace gles2 { | |
| class GLES2CmdHelper; | |
| class VertexArrayObjectManager; | |
| class ReadbackBufferShadowTracker; | |
| namespace internal { | |
| struct TextureUnit { | |
| TextureUnit() = default; | |
| // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture | |
| GLuint bound_texture_2d = 0; | |
| // texture currently bound to this unit's GL_TEXTURE_CUBE_MAP with | |
| // glBindTexture | |
| GLuint bound_texture_cube_map = 0; | |
| // texture currently bound to this unit's GL_TEXTURE_EXTERNAL_OES with | |
| // glBindTexture | |
| GLuint bound_texture_external_oes = 0; | |
| // texture currently bound to this unit's GL_TEXTURE_RECTANGLE_ARB with | |
| // glBindTexture | |
| GLuint bound_texture_rectangle_arb = 0; | |
| }; | |
| } // namespace internal | |
| // This class emulates GLES2 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. See gl2_lib.h. Note that there is a performance gain to | |
| // be had by changing your code to use command buffers directly by using the | |
| // GLES2CmdHelper but that entails changing your code to use and deal with | |
| // shared memory and synchronization issues. | |
| class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface, | |
| public ImplementationBase, | |
| public QueryTrackerClient { | |
| public: | |
| // Stores GL state that never changes. | |
| struct GLES2_IMPL_EXPORT GLStaticState { | |
| GLStaticState(); | |
| ~GLStaticState(); | |
| typedef std::pair<GLenum, GLenum> ShaderPrecisionKey; | |
| typedef std::map<ShaderPrecisionKey, | |
| cmds::GetShaderPrecisionFormat::Result> | |
| ShaderPrecisionMap; | |
| ShaderPrecisionMap shader_precisions; | |
| }; | |
| // GL names for the buffers used to emulate client side buffers. | |
| static const GLuint kClientSideArrayId = 0xFEDCBA98u; | |
| static const GLuint kClientSideElementArrayId = 0xFEDCBA99u; | |
| GLES2Implementation(GLES2CmdHelper* helper, | |
| scoped_refptr<ShareGroup> share_group, | |
| TransferBufferInterface* transfer_buffer, | |
| bool lose_context_when_out_of_memory, | |
| GpuControl* gpu_control); | |
| GLES2Implementation(const GLES2Implementation&) = delete; | |
| GLES2Implementation& operator=(const GLES2Implementation&) = delete; | |
| ~GLES2Implementation() override; | |
| gpu::ContextResult Initialize(const SharedMemoryLimits& limits); | |
| // The GLES2CmdHelper being used by this GLES2Implementation. You can use | |
| // this to issue cmds at a lower level for certain kinds of optimization. | |
| GLES2CmdHelper* helper() const; | |
| // GLES2Interface implementation | |
| void FreeSharedMemory(void*) override; | |
| bool CanCopySharedImageDirectlyToGLTexture( | |
| bool is_opaque, | |
| ClientSharedImage* shared_image, | |
| uint32_t dst_target, | |
| uint32_t dst_internal_format, | |
| uint32_t dst_type, | |
| int32_t dst_level, | |
| SkAlphaType dst_alpha_type) override; | |
| CopySharedImageSyncCallback CopySharedImageToGLTextureViaTextureCopy( | |
| const gfx::Rect& src_rect, | |
| ClientSharedImage* source_shared_image, | |
| const gpu::SyncToken& source_sync_token, | |
| uint32_t dst_target, | |
| uint32_t dst_texture, | |
| uint32_t dst_internal_format, | |
| uint32_t dst_format, | |
| uint32_t dst_type, | |
| int32_t dst_level, | |
| SkAlphaType dst_alpha_type, | |
| GrSurfaceOrigin dst_origin) override; | |
| CopySharedImageSyncCallback CopySharedImageDirectlyToGLTexture( | |
| const gfx::Rect& src_rect, | |
| ClientSharedImage* source_shared_image, | |
| const gpu::SyncToken& source_sync_token, | |
| bool is_opaque, | |
| uint32_t dst_target, | |
| uint32_t dst_texture, | |
| uint32_t dst_internal_format, | |
| uint32_t dst_format, | |
| uint32_t dst_type, | |
| int32_t dst_level, | |
| SkAlphaType dst_alpha_type, | |
| GrSurfaceOrigin dst_origin) 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/gles2_implementation_autogen.h" | |
| // 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; | |
| void GetProgramInfoCHROMIUMHelper(GLuint program, | |
| std::vector<int8_t>* result); | |
| GLint GetAttribLocationHelper(GLuint program, const char* name); | |
| GLint GetUniformLocationHelper(GLuint program, const char* name); | |
| GLint GetFragDataIndexEXTHelper(GLuint program, const char* name); | |
| GLint GetFragDataLocationHelper(GLuint program, const char* name); | |
| // Writes the result bucket into a buffer pointed by name and of maximum size | |
| // buffsize. If length is !null, it receives the number of characters written | |
| // (excluding the final \0). This is a helper function for GetActive*Helper | |
| // functions that return names. | |
| void GetResultNameHelper(GLsizei bufsize, GLsizei* length, char* name); | |
| bool GetActiveAttribHelper( | |
| GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | |
| GLint* size, GLenum* type, char* name); | |
| bool GetActiveUniformHelper( | |
| GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | |
| GLint* size, GLenum* type, char* name); | |
| void GetUniformBlocksCHROMIUMHelper(GLuint program, | |
| std::vector<int8_t>* result); | |
| void GetUniformsES3CHROMIUMHelper(GLuint program, | |
| std::vector<int8_t>* result); | |
| GLuint GetUniformBlockIndexHelper(GLuint program, const char* name); | |
| bool GetActiveUniformBlockNameHelper( | |
| GLuint program, GLuint index, GLsizei bufsize, | |
| GLsizei* length, char* name); | |
| bool GetActiveUniformBlockivHelper( | |
| GLuint program, GLuint index, GLenum pname, GLint* params); | |
| void GetTransformFeedbackVaryingsCHROMIUMHelper(GLuint program, | |
| std::vector<int8_t>* result); | |
| bool GetTransformFeedbackVaryingHelper( | |
| GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | |
| GLint* size, GLenum* type, char* name); | |
| bool GetUniformIndicesHelper( | |
| GLuint program, GLsizei count, const char* const* names, GLuint* indices); | |
| bool GetActiveUniformsivHelper( | |
| GLuint program, GLsizei count, const GLuint* indices, | |
| GLenum pname, GLint* params); | |
| bool GetSyncivHelper( | |
| GLsync sync, GLenum pname, GLsizei bufsize, GLsizei* length, | |
| GLint* values); | |
| bool GetQueryObjectValueHelper( | |
| const char* function_name, GLuint id, GLenum pname, GLuint64* params); | |
| const GLCapabilities& gl_capabilities() const { return gl_capabilities_; } | |
| const scoped_refptr<ShareGroup>& share_group() const { return share_group_; } | |
| GpuControl* gpu_control() { | |
| return gpu_control_; | |
| } | |
| ShareGroupContextData* share_group_context_data() { | |
| return &share_group_context_data_; | |
| } | |
| // 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; | |
| CommandBuffer* command_buffer() const; | |
| private: | |
| friend class GLES2ImplementationTest; | |
| friend class VertexArrayObjectManager; | |
| friend class QueryTracker; | |
| using IdNamespaces = id_namespaces::IdNamespaces; | |
| // Used to track whether an extension is available | |
| enum ExtensionStatus { | |
| kAvailableExtensionStatus, | |
| kUnavailableExtensionStatus, | |
| kUnknownExtensionStatus | |
| }; | |
| enum Dimension { | |
| k2D, | |
| k3D, | |
| }; | |
| // Base class for mapped resources. | |
| struct MappedResource { | |
| MappedResource(GLenum _access, | |
| int _shm_id, | |
| base::span<uint8_t> span, | |
| unsigned int offset) | |
| : access(_access), | |
| shm_id(_shm_id), | |
| shm_memory(span), | |
| shm_offset(offset) {} | |
| // access mode. Currently only GL_WRITE_ONLY is valid | |
| GLenum access; | |
| // Shared memory ID for buffer. | |
| int shm_id; | |
| // Shared memory buffer as a byte span. | |
| base::raw_span<uint8_t> shm_memory; | |
| // Offset of shared memory | |
| unsigned int shm_offset; | |
| }; | |
| // Used to track mapped textures. | |
| struct MappedTexture : public MappedResource { | |
| MappedTexture(GLenum access, | |
| int shm_id, | |
| base::span<uint8_t> span, | |
| unsigned int shm_offset, | |
| GLenum _target, | |
| GLint _level, | |
| GLint _xoffset, | |
| GLint _yoffset, | |
| GLsizei _width, | |
| GLsizei _height, | |
| GLenum _format, | |
| GLenum _type) | |
| : MappedResource(access, shm_id, span, shm_offset), | |
| target(_target), | |
| level(_level), | |
| xoffset(_xoffset), | |
| yoffset(_yoffset), | |
| width(_width), | |
| height(_height), | |
| format(_format), | |
| type(_type) {} | |
| // These match the arguments to TexSubImage2D. | |
| GLenum target; | |
| GLint level; | |
| GLint xoffset; | |
| GLint yoffset; | |
| GLsizei width; | |
| GLsizei height; | |
| GLenum format; | |
| GLenum type; | |
| }; | |
| // Used to track mapped buffers. | |
| struct MappedBuffer : public MappedResource { | |
| MappedBuffer(GLenum access, | |
| int shm_id, | |
| base::span<uint8_t> span, | |
| unsigned int shm_offset, | |
| GLenum _target, | |
| GLintptr _offset, | |
| GLsizeiptr _size) | |
| : MappedResource(access, shm_id, span, shm_offset), | |
| target(_target), | |
| offset(_offset), | |
| size(_size) {} | |
| // These match the arguments to BufferSubData. | |
| GLenum target; | |
| GLintptr offset; | |
| GLsizeiptr size; | |
| }; | |
| // Prevents problematic reentrancy during error callbacks. | |
| class DeferErrorCallbacks { | |
| STACK_ALLOCATED(); | |
| public: | |
| explicit DeferErrorCallbacks(GLES2Implementation* gles2_implementation); | |
| ~DeferErrorCallbacks(); | |
| private: | |
| // not using raw_ptr<> here for performance reasons. A CHECK() in | |
| // ~GLES2Implementation() assures lifetime invariants instead. | |
| GLES2Implementation& gles2_implementation_; | |
| }; | |
| struct DeferredErrorCallback { | |
| // This takes std::string by value and uses std::move in the | |
| // implementation, allowing the compiler to achieve zero copies | |
| // when passing in a temporary. | |
| DeferredErrorCallback(std::string message, int32_t id); | |
| std::string message; | |
| int32_t id = 0; | |
| }; | |
| // Checks for single threaded access. | |
| class SingleThreadChecker { | |
| public: | |
| explicit SingleThreadChecker(GLES2Implementation* gles2_implementation); | |
| ~SingleThreadChecker(); | |
| private: | |
| raw_ptr<GLES2Implementation> gles2_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; | |
| void SendErrorMessage(std::string message, int32_t id); | |
| void CallDeferredErrorCallbacks(); | |
| bool IsChromiumFramebufferMultisampleAvailable(); | |
| bool IsExtensionAvailableHelper( | |
| const char* extension, ExtensionStatus* status); | |
| // 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); | |
| // Returns the last error and clears it. Useful for debugging. | |
| const std::string& GetLastError() { | |
| return last_error_; | |
| } | |
| void AllocateShadowCopiesForReadback(); | |
| static void BufferShadowWrittenCallback( | |
| const ReadbackBufferShadowTracker::BufferList& buffers, | |
| uint64_t serial); | |
| // Returns true if id is reserved. | |
| bool IsBufferReservedId(GLuint id); | |
| bool IsFramebufferReservedId(GLuint id) { return false; } | |
| bool IsRenderbufferReservedId(GLuint id) { return false; } | |
| bool IsTextureReservedId(GLuint id) { return false; } | |
| bool IsVertexArrayReservedId(GLuint id) { return false; } | |
| bool IsProgramReservedId(GLuint id) { return false; } | |
| bool IsSamplerReservedId(GLuint id) { return false; } | |
| bool IsTransformFeedbackReservedId(GLuint id) { return false; } | |
| bool UpdateIndexedBufferState(GLenum target, | |
| GLuint index, | |
| GLuint buffer_id, | |
| const char* function_name); | |
| void BindBufferHelper(GLenum target, GLuint buffer); | |
| void BindBufferBaseHelper(GLenum target, GLuint index, GLuint buffer); | |
| void BindBufferRangeHelper(GLenum target, GLuint index, GLuint buffer, | |
| GLintptr offset, GLsizeiptr size); | |
| void BindFramebufferHelper(GLenum target, GLuint framebuffer); | |
| void BindRenderbufferHelper(GLenum target, GLuint renderbuffer); | |
| void BindSamplerHelper(GLuint unit, GLuint sampler); | |
| void BindTextureHelper(GLenum target, GLuint texture); | |
| void BindTransformFeedbackHelper(GLenum target, GLuint transformfeedback); | |
| void BindVertexArrayOESHelper(GLuint array); | |
| void UseProgramHelper(GLuint program); | |
| void BindBufferStub(GLenum target, GLuint buffer); | |
| void BindBufferBaseStub(GLenum target, GLuint index, GLuint buffer); | |
| void BindBufferRangeStub(GLenum target, GLuint index, GLuint buffer, | |
| GLintptr offset, GLsizeiptr size); | |
| void BindRenderbufferStub(GLenum target, GLuint renderbuffer); | |
| void BindTextureStub(GLenum target, GLuint texture); | |
| void GenBuffersHelper(GLsizei n, const GLuint* buffers); | |
| void GenFramebuffersHelper(GLsizei n, const GLuint* framebuffers); | |
| void GenRenderbuffersHelper(GLsizei n, const GLuint* renderbuffers); | |
| void GenTexturesHelper(GLsizei n, const GLuint* textures); | |
| void GenVertexArraysOESHelper(GLsizei n, const GLuint* arrays); | |
| void GenQueriesEXTHelper(GLsizei n, const GLuint* queries); | |
| void GenSamplersHelper(GLsizei n, const GLuint* samplers); | |
| void GenTransformFeedbacksHelper(GLsizei n, const GLuint* transformfeedbacks); | |
| void DeleteBuffersHelper(GLsizei n, const GLuint* buffers); | |
| void DeleteFramebuffersHelper(GLsizei n, const GLuint* framebuffers); | |
| void DeleteRenderbuffersHelper(GLsizei n, const GLuint* renderbuffers); | |
| void DeleteTexturesHelper(GLsizei n, const GLuint* textures); | |
| void UnbindTexturesHelper(GLsizei n, const GLuint* textures); | |
| bool DeleteProgramHelper(GLuint program); | |
| bool DeleteShaderHelper(GLuint shader); | |
| void DeleteQueriesEXTHelper(GLsizei n, const GLuint* queries); | |
| void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* arrays); | |
| void DeleteSamplersHelper(GLsizei n, const GLuint* samplers); | |
| void DeleteTransformFeedbacksHelper( | |
| GLsizei n, const GLuint* transformfeedbacks); | |
| void DeleteSyncHelper(GLsync sync); | |
| void DeleteBuffersStub(GLsizei n, const GLuint* buffers); | |
| void DeleteRenderbuffersStub(GLsizei n, const GLuint* renderbuffers); | |
| void DeleteTexturesStub(GLsizei n, const GLuint* textures); | |
| void DeleteProgramStub(GLsizei n, const GLuint* programs); | |
| void DeleteShaderStub(GLsizei n, const GLuint* shaders); | |
| void DeleteSamplersStub(GLsizei n, const GLuint* samplers); | |
| void DeleteSyncStub(GLsizei n, const GLuint* syncs); | |
| void DestroyGpuFenceCHROMIUMHelper(GLuint client_id); | |
| void BufferDataHelper( | |
| GLenum target, GLsizeiptr size, const void* data, GLenum usage); | |
| void BufferSubDataHelper( | |
| GLenum target, GLintptr offset, GLsizeiptr size, const void* data); | |
| void BufferSubDataHelperImpl( | |
| GLenum target, GLintptr offset, GLsizeiptr size, const void* data, | |
| ScopedTransferBufferPtr* buffer); | |
| void MultiDrawArraysWEBGLHelper(GLenum mode, | |
| const GLint* firsts, | |
| const GLsizei* counts, | |
| GLsizei drawcount); | |
| void MultiDrawArraysInstancedWEBGLHelper(GLenum mode, | |
| const GLint* firsts, | |
| const GLsizei* counts, | |
| const GLsizei* instanceCounts, | |
| GLsizei drawcount); | |
| void MultiDrawArraysInstancedBaseInstanceWEBGLHelper( | |
| GLenum mode, | |
| const GLint* firsts, | |
| const GLsizei* counts, | |
| const GLsizei* instanceCounts, | |
| const GLuint* baseInstances, | |
| GLsizei drawcount); | |
| void MultiDrawElementsWEBGLHelper(GLenum mode, | |
| const GLsizei* counts, | |
| GLenum type, | |
| const GLsizei* offsets, | |
| GLsizei drawcount); | |
| void MultiDrawElementsInstancedWEBGLHelper(GLenum mode, | |
| const GLsizei* counts, | |
| GLenum type, | |
| const GLsizei* offsets, | |
| const GLsizei* instanceCounts, | |
| GLsizei drawcount); | |
| void MultiDrawElementsInstancedBaseVertexBaseInstanceWEBGLHelper( | |
| GLenum mode, | |
| const GLsizei* counts, | |
| GLenum type, | |
| const GLsizei* offsets, | |
| const GLsizei* instanceCounts, | |
| const GLint* baseVertices, | |
| const GLuint* baseInstances, | |
| GLsizei drawcount); | |
| // Helper for GetVertexAttrib | |
| bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32_t* param); | |
| GLuint GetMaxValueInBufferCHROMIUMHelper( | |
| GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); | |
| void WaitAllAsyncTexImage2DCHROMIUMHelper(); | |
| // The pixels pointer should already account for unpack skip | |
| // images/rows/pixels. | |
| void TexSubImage2DImpl(GLenum target, | |
| GLint level, | |
| GLint xoffset, | |
| GLint yoffset, | |
| GLsizei width, | |
| GLsizei height, | |
| GLenum format, | |
| GLenum type, | |
| uint32_t unpadded_row_size, | |
| base::span<const uint8_t> pixels, | |
| uint32_t pixels_padded_row_size, | |
| GLboolean internal, | |
| ScopedTransferBufferPtr* buffer, | |
| uint32_t buffer_padded_row_size); | |
| void TexSubImage3DImpl(GLenum target, | |
| GLint level, | |
| GLint xoffset, | |
| GLint yoffset, | |
| GLint zoffset, | |
| GLsizei width, | |
| GLsizei height, | |
| GLsizei depth, | |
| GLenum format, | |
| GLenum type, | |
| uint32_t unpadded_row_size, | |
| base::span<const uint8_t> pixels, | |
| uint32_t pixels_padded_row_size, | |
| GLboolean internal, | |
| ScopedTransferBufferPtr* buffer, | |
| uint32_t buffer_padded_row_size); | |
| // Helpers for query functions. | |
| bool GetHelper(GLenum pname, GLint* params); | |
| GLuint GetBoundBufferHelper(GLenum target); | |
| bool GetBooleanvHelper(GLenum pname, GLboolean* params); | |
| bool GetBooleani_vHelper(GLenum pname, GLuint index, GLboolean* data); | |
| bool GetBufferParameteri64vHelper( | |
| GLenum target, GLenum pname, GLint64* params); | |
| bool GetBufferParameterivHelper(GLenum target, GLenum pname, GLint* params); | |
| bool GetFloatvHelper(GLenum pname, GLfloat* params); | |
| bool GetFramebufferAttachmentParameterivHelper( | |
| GLenum target, GLenum attachment, GLenum pname, GLint* params); | |
| bool GetFramebufferPixelLocalStorageParameterfvANGLEHelper(GLint plane, | |
| GLenum pname, | |
| GLfloat* params); | |
| bool GetFramebufferPixelLocalStorageParameterivANGLEHelper(GLint plane, | |
| GLenum pname, | |
| GLint* params); | |
| bool GetFramebufferPixelLocalStorageParameteruivANGLEHelper(GLint plane, | |
| GLenum pname, | |
| GLuint* params); | |
| bool GetInteger64vHelper(GLenum pname, GLint64* params); | |
| bool GetIntegervHelper(GLenum pname, GLint* params); | |
| bool GetIntegeri_vHelper(GLenum pname, GLuint index, GLint* data); | |
| bool GetInteger64i_vHelper(GLenum pname, GLuint index, GLint64* data); | |
| bool GetInternalformativHelper( | |
| GLenum target, GLenum format, GLenum pname, GLsizei bufSize, | |
| GLint* params); | |
| bool GetProgramivHelper(GLuint program, GLenum pname, GLint* params); | |
| bool GetSamplerParameterfvHelper( | |
| GLuint sampler, GLenum pname, GLfloat* params); | |
| bool GetSamplerParameterivHelper( | |
| GLuint sampler, GLenum pname, GLint* params); | |
| bool GetRenderbufferParameterivHelper( | |
| GLenum target, GLenum pname, GLint* params); | |
| bool GetShaderivHelper(GLuint shader, GLenum pname, GLint* params); | |
| bool GetTexParameterfvHelper(GLenum target, GLenum pname, GLfloat* params); | |
| bool GetTexParameterivHelper(GLenum target, GLenum pname, GLint* params); | |
| const GLubyte* GetStringHelper(GLenum name); | |
| bool IsExtensionAvailable(const char* ext); | |
| // Caches certain capabilties state. Return true if cached. | |
| bool SetCapabilityState(GLenum cap, bool enabled); | |
| IdHandlerInterface* GetIdHandler(SharedIdNamespaces id_namespace) const; | |
| RangeIdHandlerInterface* GetRangeIdHandler(int id_namespace) const; | |
| // IdAllocators for objects that can't be shared among contexts. | |
| IdAllocator* GetIdAllocator(IdNamespaces id_namespace) const; | |
| void FinishHelper(); | |
| void FlushHelper(); | |
| void RunIfContextNotLost(base::OnceClosure callback); | |
| // Validate if an offset is valid, i.e., non-negative and fit into 32-bit. | |
| // If not, generate an approriate error, and return false. | |
| bool ValidateOffset(const char* func, GLintptr offset); | |
| // Validate if a size is valid, i.e., non-negative and fit into 32-bit. | |
| // If not, generate an approriate error, and return false. | |
| bool ValidateSize(const char* func, GLsizeiptr offset); | |
| // Remove the transfer buffer from the buffer tracker. For buffers used | |
| // asynchronously the memory is free:ed if the upload has completed. For | |
| // other buffers, the memory is either free:ed immediately or free:ed pending | |
| // a token. | |
| void RemoveTransferBuffer(BufferTracker::Buffer* buffer); | |
| bool GetBoundPixelTransferBuffer( | |
| GLenum target, const char* function_name, GLuint* buffer_id); | |
| BufferTracker::Buffer* GetBoundPixelTransferBufferIfValid( | |
| GLuint buffer_id, | |
| const char* function_name, GLuint offset, GLsizei size); | |
| void OnBufferWrite(GLenum target); | |
| // Pack 2D arrays of char into a bucket. | |
| // Helper function for ShaderSource(), TransformFeedbackVaryings(), etc. | |
| bool PackStringsToBucket(GLsizei count, | |
| const char* const* str, | |
| const GLint* length, | |
| const char* func_name); | |
| const std::string& GetLogPrefix() const; | |
| // 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 GL_CLIENT_FAIL_GL_ERRORS | |
| #endif | |
| #endif | |
| #if defined(GL_CLIENT_FAIL_GL_ERRORS) | |
| void CheckGLError(); | |
| void FailGLError(GLenum error); | |
| #else | |
| void CheckGLError() { } | |
| void FailGLError(GLenum /* error */) { } | |
| #endif | |
| void ClearMappedBufferMap(); | |
| void ClearMappedTextureMap(); | |
| void DrawElementsImpl(GLenum mode, GLsizei count, GLenum type, | |
| const void* indices, const char* func_name); | |
| void UpdateCachedExtensionsIfNeeded(); | |
| void InvalidateCachedExtensions(); | |
| PixelStoreParams GetUnpackParameters(Dimension dimension); | |
| GLES2Util util_; | |
| raw_ptr<GLES2CmdHelper> helper_; | |
| std::string last_error_; | |
| DebugMarkerManager debug_marker_manager_; | |
| std::string this_in_hex_; | |
| ExtensionStatus chromium_framebuffer_multisample_; | |
| GLStaticState static_state_; | |
| ClientContextState state_; | |
| // GLES specific capabilities. | |
| GLCapabilities gl_capabilities_; | |
| // pack alignment as last set by glPixelStorei | |
| GLint pack_alignment_; | |
| // pack row length as last set by glPixelStorei | |
| GLint pack_row_length_; | |
| // pack skip pixels as last set by glPixelStorei | |
| GLint pack_skip_pixels_; | |
| // pack skip rows as last set by glPixelStorei | |
| GLint pack_skip_rows_; | |
| // unpack alignment as last set by glPixelStorei | |
| GLint unpack_alignment_; | |
| // unpack row length as last set by glPixelStorei | |
| GLint unpack_row_length_; | |
| // unpack image height as last set by glPixelStorei | |
| GLint unpack_image_height_; | |
| // unpack skip rows as last set by glPixelStorei | |
| GLint unpack_skip_rows_; | |
| // unpack skip pixels as last set by glPixelStorei | |
| GLint unpack_skip_pixels_; | |
| // unpack skip images as last set by glPixelStorei | |
| GLint unpack_skip_images_; | |
| base::HeapArray<internal::TextureUnit> texture_units_; | |
| // 0 to gl_state_.max_combined_texture_image_units. | |
| GLuint active_texture_unit_; | |
| GLuint bound_framebuffer_; | |
| GLuint bound_read_framebuffer_; | |
| GLuint bound_renderbuffer_; | |
| // The program in use by glUseProgram | |
| GLuint current_program_; | |
| GLuint bound_array_buffer_; | |
| GLuint bound_copy_read_buffer_; | |
| GLuint bound_copy_write_buffer_; | |
| GLuint bound_pixel_pack_buffer_; | |
| GLuint bound_pixel_unpack_buffer_; | |
| GLuint bound_transform_feedback_buffer_; | |
| GLuint bound_uniform_buffer_; | |
| // We don't cache the currently bound transform feedback buffer, because | |
| // it is part of the current transform feedback object. Caching the transform | |
| // feedback object state correctly requires predicting if a call to | |
| // glBeginTransformFeedback will succeed or fail, which in turn requires | |
| // caching a whole bunch of other states such as the transform feedback | |
| // varyings of the current program. | |
| // The currently bound pixel transfer buffers. | |
| GLuint bound_pixel_pack_transfer_buffer_id_; | |
| GLuint bound_pixel_unpack_transfer_buffer_id_; | |
| // Client side management for vertex array objects. Needed to correctly | |
| // track client side arrays. | |
| std::unique_ptr<VertexArrayObjectManager> vertex_array_object_manager_; | |
| // 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_; | |
| // Changed every time a flush or finish occurs. | |
| uint32_t flush_id_; | |
| // Avoid recycling of client-allocated GpuFence IDs by saving the | |
| // last-allocated one and requesting the next one to be higher than that. | |
| // This will wrap around as needed, but the space should be plenty big enough | |
| // to avoid collisions. | |
| uint32_t last_gpu_fence_id_ = 0; | |
| // Maximum amount of extra memory from the mapped memory pool to use when | |
| // needing to transfer something exceeding the default transfer buffer. | |
| uint32_t max_extra_transfer_buffer_size_; | |
| // Set of strings returned from glGetString. We need to cache these because | |
| // the pointer passed back to the client has to remain valid for eternity. | |
| std::set<std::string> gl_strings_; | |
| // TODO(crbug.com/40285824): Spanify `mapped_buffers_` to use | |
| // base::span<uint8_t> instead of void*. | |
| typedef std::map<const void*, MappedBuffer> MappedBufferMap; | |
| MappedBufferMap mapped_buffers_; | |
| // TODO(crbug.com/40285824): Spanify `mapped_textures_` to use | |
| // base::span<uint8_t> instead of void*. | |
| typedef std::map<const void*, MappedTexture> MappedTextureMap; | |
| MappedTextureMap mapped_textures_; | |
| scoped_refptr<ShareGroup> share_group_; | |
| ShareGroupContextData share_group_context_data_; | |
| std::array<std::unique_ptr<IdAllocator>, | |
| static_cast<int>(IdNamespaces::kNumIdNamespaces)> | |
| id_allocators_; | |
| std::unique_ptr<BufferTracker> buffer_tracker_; | |
| std::unique_ptr<ReadbackBufferShadowTracker> readback_buffer_shadow_tracker_; | |
| std::optional<ScopedMappedMemoryPtr> font_mapped_buffer_; | |
| std::optional<ScopedTransferBufferPtr> raster_mapped_buffer_; | |
| base::RepeatingCallback<void(const char*, int32_t)> error_message_callback_; | |
| bool deferring_error_callbacks_ = false; | |
| std::deque<DeferredErrorCallback> deferred_error_callbacks_; | |
| int current_trace_stack_; | |
| // Flag to indicate whether the implementation can retain resources, or | |
| // whether it should aggressively free them. | |
| bool aggressively_free_resources_; | |
| // Result of last GetString(GL_EXTENSIONS), used to keep | |
| // GetString(GL_EXTENSIONS), GetStringi(GL_EXTENSIONS, index) and | |
| // GetIntegerv(GL_NUM_EXTENSIONS) in sync. This points to gl_strings, valid | |
| // forever. | |
| const char* cached_extension_string_; | |
| // Populated if cached_extension_string_ != nullptr. These point to | |
| // gl_strings, valid forever. | |
| std::vector<const char*> cached_extensions_; | |
| std::string last_active_url_; | |
| base::WeakPtrFactory<GLES2Implementation> weak_ptr_factory_{this}; | |
| }; | |
| inline bool GLES2Implementation::GetBufferParameteri64vHelper( | |
| GLenum /* target */, GLenum /* pname */, GLint64* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetBufferParameterivHelper( | |
| GLenum /* target */, GLenum /* pname */, GLint* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetFramebufferAttachmentParameterivHelper( | |
| GLenum /* target */, | |
| GLenum /* attachment */, | |
| GLenum /* pname */, | |
| GLint* /* params */) { | |
| return false; | |
| } | |
| inline bool | |
| GLES2Implementation::GetFramebufferPixelLocalStorageParameterfvANGLEHelper( | |
| GLint /* plane */, | |
| GLenum /* pname */, | |
| GLfloat* /* params */) { | |
| return false; | |
| } | |
| inline bool | |
| GLES2Implementation::GetFramebufferPixelLocalStorageParameterivANGLEHelper( | |
| GLint /* plane */, | |
| GLenum /* pname */, | |
| GLint* /* params */) { | |
| return false; | |
| } | |
| inline bool | |
| GLES2Implementation::GetFramebufferPixelLocalStorageParameteruivANGLEHelper( | |
| GLint /* plane */, | |
| GLenum /* pname */, | |
| GLuint* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetRenderbufferParameterivHelper( | |
| GLenum /* target */, GLenum /* pname */, GLint* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetShaderivHelper( | |
| GLuint /* shader */, GLenum /* pname */, GLint* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetTexParameterfvHelper( | |
| GLenum /* target */, GLenum /* pname */, GLfloat* /* params */) { | |
| return false; | |
| } | |
| inline bool GLES2Implementation::GetTexParameterivHelper( | |
| GLenum /* target */, GLenum /* pname */, GLint* /* params */) { | |
| return false; | |
| } | |
| } // namespace gles2 | |
| } // namespace gpu | |
| #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_ |