gpu/command_buffer/client/gles2_implementation.h - chromium/src - Git at Google (original) (raw)

// 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

#include

#include

#include

#include

#include

#include <unordered_map>

#include

#include

#include "base/compiler_specific.h"

#include "base/containers/heap_array.h"

#include "base/containers/queue.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 bind_generates_resource,

bool lose_context_when_out_of_memory,

bool support_client_side_arrays,

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;

GLboolean DidGpuSwitch(gl::GpuPreference* active_gpu) final;

// 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;

uint64_t ShareGroupTracingGUID() const override;

void SetErrorMessageCallback(

base::RepeatingCallback<void(const char*, int32_t)> callback) override;

bool ThreadSafeShallowLockDiscardableTexture(uint32_t texture_id) override;

void CompleteLockDiscardableTexureOnContextThread(

uint32_t texture_id) override;

bool ThreadsafeDiscardableTextureIsDeletedForTracing(

uint32_t texture_id) override;

void* 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;

bool IsJpegDecodeAccelerationSupported() const override;

bool IsWebPDecodeAccelerationSupported() const override;

bool CanDecodeWithHardwareAcceleration(

const cc::ImageHeaderMetadata* image_metadata) 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);

bool GetProgramInterfaceivHelper(

GLuint program, GLenum program_interface, GLenum pname, GLint* params);

GLuint GetProgramResourceIndexHelper(

GLuint program, GLenum program_interface, const char* name);

bool GetProgramResourceNameHelper(

GLuint program, GLenum program_interface, GLuint index, GLsizei bufsize,

GLsizei* length, char* name);

bool GetProgramResourceivHelper(

GLuint program, GLenum program_interface, GLuint index,

GLsizei prop_count, const GLenum* props, GLsizei bufsize, GLsizei* length,

GLint* params);

GLint GetProgramResourceLocationHelper(

GLuint program, GLenum program_interface, const char* name);

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, void* mem, unsigned int offset)

: access(_access),

shm_id(_shm_id),

shm_memory(mem),

shm_offset(offset) {}

// access mode. Currently only GL_WRITE_ONLY is valid

GLenum access;

// Shared memory ID for buffer.

int shm_id;

// Address of shared memory

raw_ptr 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,

void* shm_mem,

unsigned int shm_offset,

GLenum _target,

GLint _level,

GLint _xoffset,

GLint _yoffset,

GLsizei _width,

GLsizei _height,

GLenum _format,

GLenum _type)

: MappedResource(access, shm_id, shm_mem, 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,

void* shm_mem,

unsigned int shm_offset,

GLenum _target,

GLintptr _offset,

GLsizeiptr _size)

: MappedResource(access, shm_id, shm_mem, 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 OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) 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();

void RestoreElementAndArrayBuffers(bool restore);

void RestoreArrayBuffer(bool restrore);

// 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,

const void* 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,

const void* 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 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 RemoveMappedBufferRangeByTarget(GLenum target);

void RemoveMappedBufferRangeById(GLuint buffer);

void ClearMappedBufferRangeMap();

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::HeapArrayinternal::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_atomic_counter_buffer_;

GLuint bound_copy_read_buffer_;

GLuint bound_copy_write_buffer_;

GLuint bound_dispatch_indirect_buffer_;

GLuint bound_draw_indirect_buffer_;

GLuint bound_pixel_pack_buffer_;

GLuint bound_pixel_unpack_buffer_;

GLuint bound_shader_storage_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_;

GLuint reserved_ids_[2];

// 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_;

// Whether or not to support client side arrays.

const bool support_client_side_arrays_;

// 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::setstd::string\ gl_strings_;

typedef std::map<const void*, MappedBuffer> MappedBufferMap;

MappedBufferMap mapped_buffers_;

// TODO(zmo): Consolidate |mapped_buffers_| and |mapped_buffer_range_map_|.

typedef std::unordered_map<GLuint, MappedBuffer> MappedBufferRangeMap;

MappedBufferRangeMap mapped_buffer_range_map_;

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(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_;

bool gpu_switched_ = false;

gl::GpuPreference active_gpu_heuristic_ = gl::GpuPreference::kDefault;

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::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_