#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/sampler_manager.h"
#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
#include "gpu/command_buffer/service/texture_base.h"
#include "gpu/gpu_gles2_export.h"
#include "ui/gfx/geometry/rect.h"
namespace gl {
class GLImage;
class ProgressReporter;
}
namespace gpu {
class DecoderContext;
class ServiceDiscardableManager;
namespace gles2 {
struct ContextState;
struct DecoderFramebufferState;
class ErrorState;
class FeatureInfo;
class FramebufferManager;
class Texture;
class TextureManager;
class TextureRef;
class GPU_GLES2_EXPORT TexturePassthrough final
: public TextureBase,
public base::RefCounted<TexturePassthrough>,
public base::SupportsWeakPtr<TexturePassthrough> {
public:
TexturePassthrough(GLuint service_id, GLenum target);
TexturePassthrough(GLuint service_id,
GLenum target,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type);
TexturePassthrough(const TexturePassthrough&) = delete;
TexturePassthrough& operator=(const TexturePassthrough&) = delete;
TextureBase::Type GetType() const override;
static TexturePassthrough* CheckedCast(TextureBase* texture);
void MarkContextLost();
#if !BUILDFLAG(IS_ANDROID)
void SetLevelImage(GLenum target, GLint level, gl::GLImage* image);
gl::GLImage* GetLevelImage(GLenum target, GLint level) const;
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OHOS)
void BindToServiceId(GLuint service_id);
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
bool is_bind_pending() const { return is_bind_pending_; }
void set_bind_pending() { is_bind_pending_ = true; }
void clear_bind_pending() { is_bind_pending_ = false; }
#endif
void SetEstimatedSize(size_t size);
size_t estimated_size() const { return estimated_size_; }
protected:
~TexturePassthrough() override;
private:
bool LevelInfoExists(GLenum target, GLint level, size_t* out_face_idx) const;
#if !BUILDFLAG(IS_ANDROID)
void SetLevelImageInternal(GLenum target,
GLint level,
gl::GLImage* image,
GLuint service_id);
#endif
friend class base::RefCounted<TexturePassthrough>;
const GLuint owned_service_id_ = 0;
bool have_context_;
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
bool is_bind_pending_ = false;
#endif
size_t estimated_size_ = 0;
struct LevelInfo {
LevelInfo();
LevelInfo(const LevelInfo& rhs);
~LevelInfo();
GLenum internal_format = 0;
GLsizei width = 0;
GLsizei height = 0;
GLsizei depth = 0;
GLint border = 0;
GLenum format = 0;
GLenum type = 0;
scoped_refptr<gl::GLImage> image;
};
LevelInfo* GetLevelInfo(GLenum target, GLint level);
std::vector<std::vector<LevelInfo>> level_images_;
};
class GPU_GLES2_EXPORT Texture final : public TextureBase {
public:
enum ImageState {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
UNBOUND,
#endif
BOUND,
NOIMAGE,
};
struct CompatibilitySwizzle {
GLenum format;
GLenum dest_format;
GLenum red;
GLenum green;
GLenum blue;
GLenum alpha;
};
struct LevelInfo {
LevelInfo();
LevelInfo(const LevelInfo& rhs);
~LevelInfo();
gfx::Rect cleared_rect;
GLenum target = 0;
GLint level = -1;
GLenum internal_format = 0;
GLsizei width = 0;
GLsizei height = 0;
GLsizei depth = 0;
GLint border = 0;
GLenum format = 0;
GLenum type = 0;
scoped_refptr<gl::GLImage> image;
uint32_t estimated_size = 0;
bool internal_workaround = false;
private:
friend class Texture;
ImageState image_state = NOIMAGE;
};
explicit Texture(GLuint service_id);
Texture(const Texture&) = delete;
Texture& operator=(const Texture&) = delete;
TextureBase::Type GetType() const override;
static Texture* CheckedCast(TextureBase* texture);
const SamplerState& sampler_state() const {
return sampler_state_;
}
void set_min_filter(GLenum min_filter) {
sampler_state_.min_filter = min_filter;
}
GLenum min_filter() const {
return sampler_state_.min_filter;
}
void set_mag_filter(GLenum mag_filter) {
sampler_state_.mag_filter = mag_filter;
}
GLenum mag_filter() const {
return sampler_state_.mag_filter;
}
void set_wrap_r(GLenum wrap_r) { sampler_state_.wrap_r = wrap_r; }
GLenum wrap_r() const {
return sampler_state_.wrap_r;
}
void set_wrap_s(GLenum wrap_s) { sampler_state_.wrap_s = wrap_s; }
GLenum wrap_s() const {
return sampler_state_.wrap_s;
}
void set_wrap_t(GLenum wrap_t) { sampler_state_.wrap_t = wrap_t; }
GLenum wrap_t() const {
return sampler_state_.wrap_t;
}
GLenum usage() const {
return usage_;
}
GLenum compare_func() const {
return sampler_state_.compare_func;
}
GLenum compare_mode() const {
return sampler_state_.compare_mode;
}
GLfloat max_lod() const {
return sampler_state_.max_lod;
}
GLfloat min_lod() const {
return sampler_state_.min_lod;
}
GLint base_level() const {
return base_level_;
}
GLint max_level() const {
return max_level_;
}
GLint unclamped_base_level() const { return unclamped_base_level_; }
GLint unclamped_max_level() const { return unclamped_max_level_; }
GLenum swizzle_r() const { return swizzle_r_; }
GLenum swizzle_g() const { return swizzle_g_; }
GLenum swizzle_b() const { return swizzle_b_; }
GLenum swizzle_a() const { return swizzle_a_; }
int num_uncleared_mips() const {
return num_uncleared_mips_;
}
uint32_t estimated_size() const { return estimated_size_; }
bool CanRenderTo(const FeatureInfo* feature_info, GLint level) const;
bool SafeToRenderFrom() const {
return cleared_;
}
bool GetLevelSize(
GLint target, GLint level,
GLsizei* width, GLsizei* height, GLsizei* depth) const;
bool GetLevelType(
GLint target, GLint level, GLenum* type, GLenum* internal_format) const;
void SetBoundLevelImage(GLenum target, GLint level, gl::GLImage* image);
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
void SetUnboundLevelImage(GLenum target, GLint level, gl::GLImage* image);
#endif
void UnsetLevelImage(GLenum target, GLint level);
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OHOS)
void BindToServiceId(GLuint service_id);
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
void MarkLevelImageBound(GLenum target, GLint level);
#endif
bool CompatibleWithSamplerUniformType(
GLenum type,
const SamplerState& sampler_state) const;
gl::GLImage* GetLevelImage(GLint target, GLint level) const;
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
bool HasUnboundLevelImage(GLint target, GLint level) const;
#endif
bool HasImages() const {
return has_images_;
}
bool ValidForTexture(
GLint target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth) const;
bool IsValid() const {
return !!target();
}
bool IsAttachedToFramebuffer() const {
return framebuffer_attachment_count_ != 0;
}
void AttachToFramebuffer() {
++framebuffer_attachment_count_;
}
void DetachFromFramebuffer() {
DCHECK_GT(framebuffer_attachment_count_, 0);
--framebuffer_attachment_count_;
}
void SetImmutable(bool immutable, bool immutable_storage);
bool IsImmutable() const {
return immutable_;
}
bool HasImmutableStorage() const { return immutable_storage_; }
GLint GetImmutableLevels() const;
gfx::Rect GetLevelClearedRect(GLenum target, GLint level) const;
void SetLevelClearedRect(GLenum target,
GLint level,
const gfx::Rect& cleared_rect);
bool IsLevelCleared(GLenum target, GLint level) const;
bool IsLevelPartiallyCleared(GLenum target, GLint level) const;
bool IsDefined() const {
return estimated_size() > 0;
}
void InitTextureMaxAnisotropyIfNeeded(GLenum target);
void DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
uint64_t client_tracing_id,
const std::string& dump_name) const;
void ApplyFormatWorkarounds(const FeatureInfo* feature_info);
bool texture_complete() const {
DCHECK(!completeness_dirty_);
return texture_complete_;
}
static bool ColorRenderable(const FeatureInfo* feature_info,
GLenum internal_format,
bool immutable);
void SetLevelCleared(GLenum target, GLint level, bool cleared);
void ApplyClampedBaseLevelAndMaxLevelToDriver();
MemoryTypeTracker* GetMemTracker();
GLenum GetInternalFormatOfBaseLevel() const;
void SetLightweightRef();
void RemoveLightweightRef(bool have_context);
void SetLevelInfo(GLenum target,
GLint level,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
const gfx::Rect& cleared_rect);
const LevelInfo* GetLevelInfo(GLint target, GLint level) const;
void SetTarget(GLenum target, GLint max_levels);
void SetCompatibilitySwizzle(const CompatibilitySwizzle* swizzle);
bool NeedsMips() const {
return sampler_state_.min_filter != GL_NEAREST &&
sampler_state_.min_filter != GL_LINEAR;
}
size_t MaxValidMipLevel() const {
DCHECK(!face_infos_.empty());
return face_infos_[0].level_infos.size();
}
private:
friend class MailboxManagerTest;
friend class TextureManager;
friend class TextureRef;
friend class TextureTestHelper;
FRIEND_TEST_ALL_PREFIXES(TextureMemoryTrackerTest, LightweightRef);
~Texture() override;
void AddTextureRef(TextureRef* ref);
void RemoveTextureRef(TextureRef* ref, bool have_context);
void MaybeDeleteThis(bool have_context);
enum CanRenderCondition {
CAN_RENDER_ALWAYS,
CAN_RENDER_NEVER,
CAN_RENDER_NEEDS_VALIDATION,
};
struct FaceInfo {
FaceInfo();
FaceInfo(const FaceInfo& other);
~FaceInfo();
GLsizei num_mip_levels;
std::vector<LevelInfo> level_infos;
};
void SetLevelImageInternal(GLenum target,
GLint level,
gl::GLImage* image,
ImageState state);
const LevelInfo* GetBaseLevelInfo() const;
void SetStreamTextureServiceId(GLuint service_id);
void MarkLevelAsInternalWorkaround(GLenum target, GLint level);
bool cube_complete() const {
DCHECK(!completeness_dirty_);
return cube_complete_;
}
bool npot() const {
return npot_;
}
void UpdateCleared();
bool ClearRenderableLevels(DecoderContext* decoder);
bool ClearLevel(DecoderContext* decoder, GLenum target, GLint level);
GLenum SetParameteri(
const FeatureInfo* feature_info, GLenum pname, GLint param);
GLenum SetParameterf(
const FeatureInfo* feature_info, GLenum pname, GLfloat param);
void MarkMipmapsGenerated();
bool CanRender(const FeatureInfo* feature_info) const;
bool CanRenderWithSampler(const FeatureInfo* feature_info,
const SamplerState& sampler_state) const;
bool CanGenerateMipmaps(const FeatureInfo* feature_info) const;
static bool TextureIsNPOT(GLsizei width, GLsizei height, GLsizei depth);
static bool TextureFaceComplete(const Texture::LevelInfo& first_face,
size_t face_index,
GLenum target,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLenum type);
static bool TextureMipComplete(const Texture::LevelInfo& base_level_face,
GLenum target,
GLint level_diff,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLenum type);
static bool TextureFilterable(const FeatureInfo* feature_info,
GLenum internal_format,
GLenum type,
bool immutable);
void Update();
void AddToSignature(
const FeatureInfo* feature_info,
GLenum target, GLint level, std::string* signature) const;
void UpdateSafeToRenderFrom(bool cleared);
void UpdateMipCleared(LevelInfo* info,
GLsizei width,
GLsizei height,
const gfx::Rect& cleared_rect);
CanRenderCondition GetCanRenderCondition() const;
void UpdateCanRenderCondition();
void UpdateHasImages();
void IncAllFramebufferStateChangeCount();
void UpdateBaseLevel(GLint base_level, const FeatureInfo* feature_info);
void UpdateMaxLevel(GLint max_level);
void UpdateFaceNumMipLevels(size_t face_index,
GLint width,
GLint height,
GLint depth);
void UpdateFaceNumMipLevels(size_t face_index);
void UpdateNumMipLevels();
void IncrementManagerServiceIdGeneration();
GLuint owned_service_id() const { return owned_service_id_; }
GLenum GetCompatibilitySwizzleForChannel(GLenum channel);
std::vector<FaceInfo> face_infos_;
typedef base::flat_set<TextureRef*> RefSet;
RefSet refs_;
bool has_lightweight_ref_ = false;
raw_ptr<TextureRef> memory_tracking_ref_ = nullptr;
GLuint owned_service_id_;
bool cleared_ = true;
int num_uncleared_mips_ = 0;
int num_npot_faces_ = 0;
SamplerState sampler_state_;
GLenum usage_ = GL_NONE;
GLint base_level_ = 0;
GLint max_level_ = 1000;
GLenum swizzle_r_ = GL_RED;
GLenum swizzle_g_ = GL_GREEN;
GLenum swizzle_b_ = GL_BLUE;
GLenum swizzle_a_ = GL_ALPHA;
GLint unclamped_base_level_ = 0;
GLint unclamped_max_level_ = 1000;
GLint max_level_set_ = -1;
bool texture_complete_ = false;
bool cube_complete_ = false;
bool completeness_dirty_ = false;
bool npot_ = false;
bool has_been_bound_ = false;
int framebuffer_attachment_count_ = 0;
bool immutable_ = false;
bool immutable_storage_ = false;
bool has_images_ = false;
uint32_t estimated_size_ = 0;
CanRenderCondition can_render_condition_ = CAN_RENDER_ALWAYS;
bool texture_max_anisotropy_initialized_ = false;
raw_ptr<const CompatibilitySwizzle> compatibility_swizzle_ = nullptr;
};
class GPU_GLES2_EXPORT TextureRef : public base::RefCounted<TextureRef> {
public:
TextureRef(TextureManager* manager, GLuint client_id, Texture* texture);
TextureRef(const TextureRef&) = delete;
TextureRef& operator=(const TextureRef&) = delete;
static scoped_refptr<TextureRef> Create(TextureManager* manager,
GLuint client_id,
GLuint service_id);
void AddObserver() { num_observers_++; }
void RemoveObserver() { num_observers_--; }
void SetSharedImageRepresentation(
std::unique_ptr<GLTextureImageRepresentation> shared_image);
const Texture* texture() const { return texture_; }
Texture* texture() { return texture_; }
GLuint client_id() const { return client_id_; }
GLuint service_id() const { return texture_->service_id(); }
GLint num_observers() const { return num_observers_; }
GLTextureImageRepresentation* shared_image() const {
return shared_image_.get();
}
const std::unique_ptr<GLTextureImageRepresentation::ScopedAccess>&
shared_image_scoped_access() const {
return shared_image_scoped_access_;
}
bool BeginAccessSharedImage(GLenum mode);
void EndAccessSharedImage();
void ForceContextLost();
private:
friend class base::RefCounted<TextureRef>;
friend class Texture;
friend class TextureManager;
~TextureRef();
const TextureManager* manager() const { return manager_; }
TextureManager* manager() { return manager_; }
void reset_client_id() { client_id_ = 0; }
raw_ptr<TextureManager> manager_;
raw_ptr<Texture, DanglingUntriaged> texture_;
GLuint client_id_;
GLint num_observers_;
bool force_context_lost_;
std::unique_ptr<GLTextureImageRepresentation> shared_image_;
std::unique_ptr<GLTextureImageRepresentation::ScopedAccess>
shared_image_scoped_access_;
};
struct DecoderTextureState {
explicit DecoderTextureState(const GpuDriverBugWorkarounds& workarounds);
bool tex_image_failed;
bool force_cube_map_positive_x_allocation;
bool force_cube_complete;
bool force_int_or_srgb_cube_texture_complete;
bool unpack_alignment_workaround_with_unpack_buffer;
bool unpack_overlapping_rows_separately_unpack_buffer;
bool unpack_image_height_workaround_with_unpack_buffer;
};
class GPU_GLES2_EXPORT TextureManager
: public base::trace_event::MemoryDumpProvider {
public:
class GPU_GLES2_EXPORT DestructionObserver {
public:
DestructionObserver();
DestructionObserver(const DestructionObserver&) = delete;
DestructionObserver& operator=(const DestructionObserver&) = delete;
virtual ~DestructionObserver();
virtual void OnTextureManagerDestroying(TextureManager* manager) = 0;
virtual void OnTextureRefDestroying(TextureRef* texture) = 0;
};
enum DefaultAndBlackTextures {
kTexture2D,
kTexture3D,
kTexture2DArray,
kCubeMap,
kExternalOES,
kRectangleARB,
kNumDefaultTextures
};
TextureManager(MemoryTracker* memory_tracker,
FeatureInfo* feature_info,
GLsizei max_texture_size,
GLsizei max_cube_map_texture_size,
GLsizei max_rectangle_texture_size,
GLsizei max_3d_texture_size,
GLsizei max_array_texture_layers,
bool use_default_textures,
gl::ProgressReporter* progress_reporter,
ServiceDiscardableManager* discardable_manager);
TextureManager(const TextureManager&) = delete;
TextureManager& operator=(const TextureManager&) = delete;
~TextureManager() override;
void AddFramebufferManager(FramebufferManager* framebuffer_manager);
void RemoveFramebufferManager(FramebufferManager* framebuffer_manager);
void Initialize();
void MarkContextLost();
void Destroy();
GLint MaxLevelsForTarget(GLenum target) const {
switch (target) {
case GL_TEXTURE_2D:
case GL_TEXTURE_2D_ARRAY:
return max_levels_;
case GL_TEXTURE_RECTANGLE_ARB:
case GL_TEXTURE_EXTERNAL_OES:
return 1;
case GL_TEXTURE_3D:
return max_3d_levels_;
default:
return max_cube_map_levels_;
}
}
GLsizei MaxSizeForTarget(GLenum target) const {
switch (target) {
case GL_TEXTURE_2D:
case GL_TEXTURE_EXTERNAL_OES:
case GL_TEXTURE_2D_ARRAY:
return max_texture_size_;
case GL_TEXTURE_RECTANGLE:
return max_rectangle_texture_size_;
case GL_TEXTURE_3D:
return max_3d_texture_size_;
default:
return max_cube_map_texture_size_;
}
}
GLsizei max_array_texture_layers() const {
return max_array_texture_layers_;
}
static GLsizei ComputeMipMapCount(GLenum target,
GLsizei width,
GLsizei height,
GLsizei depth);
static GLenum ExtractFormatFromStorageFormat(GLenum internalformat);
static GLenum ExtractTypeFromStorageFormat(GLenum internalformat);
bool ValidForTarget(
GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth);
bool ValidForTextureTarget(const Texture* texture,
GLint level,
GLsizei width,
GLsizei height,
GLsizei depth);
bool CanRender(const TextureRef* ref) const {
return ref->texture()->CanRender(feature_info_.get());
}
bool CanRenderWithSampler(
const TextureRef* ref, const SamplerState& sampler_state) const {
return ref->texture()->CanRenderWithSampler(
feature_info_.get(), sampler_state);
}
bool CanGenerateMipmaps(const TextureRef* ref) const {
return ref->texture()->CanGenerateMipmaps(feature_info_.get());
}
void SetTarget(
TextureRef* ref,
GLenum target);
void SetLevelInfo(TextureRef* ref,
GLenum target,
GLint level,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
const gfx::Rect& cleared_rect);
TextureRef* Consume(GLuint client_id, Texture* texture);
TextureRef* ConsumeSharedImage(
GLuint client_id,
std::unique_ptr<GLTextureImageRepresentation> shared_image);
void SetLevelClearedRect(TextureRef* ref,
GLenum target,
GLint level,
const gfx::Rect& cleared_rect);
void SetLevelCleared(TextureRef* ref, GLenum target,
GLint level, bool cleared);
void SetParameteri(
const char* function_name, ErrorState* error_state,
TextureRef* ref, GLenum pname, GLint param);
void SetParameterf(
const char* function_name, ErrorState* error_state,
TextureRef* ref, GLenum pname, GLfloat param);
void MarkMipmapsGenerated(TextureRef* ref);
bool ClearRenderableLevels(DecoderContext* decoder, TextureRef* ref);
static bool ClearTextureLevel(DecoderContext* decoder,
TextureRef* ref,
GLenum target,
GLint level);
static bool ClearTextureLevel(DecoderContext* decoder,
Texture* texture,
GLenum target,
GLint level);
TextureRef* CreateTexture(GLuint client_id, GLuint service_id);
TextureRef* GetTexture(GLuint client_id) const;
scoped_refptr<TextureRef> TakeTexture(GLuint client_id);
void ReturnTexture(scoped_refptr<TextureRef> texture_ref);
void RemoveTexture(GLuint client_id);
Texture* GetTextureForServiceId(GLuint service_id) const;
TextureRef* GetDefaultTextureInfo(GLenum target) {
switch (target) {
case GL_TEXTURE_2D:
return default_textures_[kTexture2D].get();
case GL_TEXTURE_3D:
return default_textures_[kTexture3D].get();
case GL_TEXTURE_2D_ARRAY:
return default_textures_[kTexture2DArray].get();
case GL_TEXTURE_CUBE_MAP:
return default_textures_[kCubeMap].get();
case GL_TEXTURE_EXTERNAL_OES:
return default_textures_[kExternalOES].get();
case GL_TEXTURE_RECTANGLE_ARB:
return default_textures_[kRectangleARB].get();
default:
NOTREACHED();
return nullptr;
}
}
bool HaveUnsafeTextures() const {
return num_unsafe_textures_ > 0;
}
bool HaveUnclearedMips() const {
return num_uncleared_mips_ > 0;
}
bool HaveImages() const {
return num_images_ > 0;
}
GLuint black_texture_id(GLenum target) const {
switch (target) {
case GL_SAMPLER_2D:
return black_texture_ids_[kTexture2D];
case GL_SAMPLER_3D:
return black_texture_ids_[kTexture3D];
case GL_SAMPLER_2D_ARRAY:
return black_texture_ids_[kTexture2DArray];
case GL_SAMPLER_CUBE:
return black_texture_ids_[kCubeMap];
case GL_SAMPLER_EXTERNAL_OES:
return black_texture_ids_[kExternalOES];
case GL_SAMPLER_2D_RECT_ARB:
return black_texture_ids_[kRectangleARB];
default:
return 0;
}
}
size_t mem_represented() const {
return memory_type_tracker_->GetMemRepresented();
}
void SetBoundLevelImage(TextureRef* ref,
GLenum target,
GLint level,
gl::GLImage* image);
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
void SetUnboundLevelImage(TextureRef* ref,
GLenum target,
GLint level,
gl::GLImage* image);
#endif
void UnsetLevelImage(TextureRef* ref, GLenum target, GLint level);
size_t GetSignatureSize() const;
void AddToSignature(
TextureRef* ref,
GLenum target,
GLint level,
std::string* signature) const;
void AddObserver(DestructionObserver* observer) {
destruction_observers_.push_back(observer);
}
void RemoveObserver(DestructionObserver* observer) {
for (unsigned int i = 0; i < destruction_observers_.size(); i++) {
if (destruction_observers_[i] == observer) {
std::swap(destruction_observers_[i], destruction_observers_.back());
destruction_observers_.pop_back();
return;
}
}
NOTREACHED();
}
struct DoTexImageArguments {
enum class CommandType {
kTexImage2D,
kTexImage3D,
};
GLenum target;
GLint level;
GLenum internal_format;
GLsizei width;
GLsizei height;
GLsizei depth;
GLint border;
GLenum format;
GLenum type;
RAW_PTR_EXCLUSION const void* pixels;
uint32_t pixels_size;
uint32_t padding;
CommandType command_type;
};
bool ValidateTexImage(ContextState* state,
ErrorState* error_state,
const char* function_name,
const DoTexImageArguments& args,
TextureRef** texture_ref);
void ValidateAndDoTexImage(DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
const char* function_name,
const DoTexImageArguments& args);
struct DoTexSubImageArguments {
enum class CommandType {
kTexSubImage2D,
kTexSubImage3D,
};
GLenum target;
GLint level;
GLint xoffset;
GLint yoffset;
GLint zoffset;
GLsizei width;
GLsizei height;
GLsizei depth;
GLenum format;
GLenum type;
RAW_PTR_EXCLUSION const void* pixels;
uint32_t pixels_size;
uint32_t padding;
CommandType command_type;
};
bool ValidateTexSubImage(ContextState* state,
ErrorState* error_state,
const char* function_name,
const DoTexSubImageArguments& args,
TextureRef** texture_ref);
void ValidateAndDoTexSubImage(DecoderContext* decoder,
DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
const char* function_name,
const DoTexSubImageArguments& args);
TextureRef* GetTextureInfoForTarget(ContextState* state, GLenum target);
TextureRef* GetTextureInfoForTargetUnlessDefault(
ContextState* state, GLenum target);
bool ValidateTextureParameters(
ErrorState* error_state, const char* function_name, bool tex_image_call,
GLenum format, GLenum type, GLint internal_format, GLint level);
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
static bool CombineAdjacentRects(const gfx::Rect& rect1,
const gfx::Rect& rect2,
gfx::Rect* result);
uint32_t GetServiceIdGeneration() const;
void IncrementServiceIdGeneration();
static const Texture::CompatibilitySwizzle* GetCompatibilitySwizzle(
const gles2::FeatureInfo* feature_info,
GLenum format);
static GLenum AdjustTexInternalFormat(const gles2::FeatureInfo* feature_info,
GLenum format,
GLenum type);
static GLenum AdjustTexFormat(const gles2::FeatureInfo* feature_info,
GLenum format);
static GLenum AdjustTexStorageFormat(const gles2::FeatureInfo* feature_info,
GLenum format);
void WorkaroundCopyTexImageCubeMap(DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
TextureRef* texture_ref,
const char* function_name,
const DoTexImageArguments& args) {
DoCubeMapWorkaround(texture_state, state, error_state, framebuffer_state,
texture_ref, function_name, args);
}
private:
friend class Texture;
friend class TextureRef;
scoped_refptr<TextureRef> CreateDefaultAndBlackTextures(
GLenum target,
GLuint* black_texture);
void DoTexImage(DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
const char* function_name,
TextureRef* texture_ref,
const DoTexImageArguments& args);
void ReserveTexImageToBeFilled(DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
const char* function_name,
TextureRef* texture_ref,
const DoTexImageArguments& args);
void DoTexSubImageWithAlignmentWorkaround(
DecoderTextureState* texture_state,
ContextState* state,
const DoTexSubImageArguments& args);
void DoTexSubImageRowByRowWorkaround(DecoderTextureState* texture_state,
ContextState* state,
const DoTexSubImageArguments& args,
const PixelStoreParams& unpack_params);
void DoTexSubImageLayerByLayerWorkaround(
DecoderTextureState* texture_state,
ContextState* state,
const DoTexSubImageArguments& args,
const PixelStoreParams& unpack_params);
void DoCubeMapWorkaround(DecoderTextureState* texture_state,
ContextState* state,
ErrorState* error_state,
DecoderFramebufferState* framebuffer_state,
TextureRef* texture_ref,
const char* function_name,
const DoTexImageArguments& args);
void StartTracking(TextureRef* texture);
void StopTracking(TextureRef* texture);
void UpdateSafeToRenderFrom(int delta);
void UpdateUnclearedMips(int delta);
void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition,
Texture::CanRenderCondition new_condition);
void UpdateNumImages(int delta);
void IncFramebufferStateChangeCount();
void DumpTextureRef(base::trace_event::ProcessMemoryDump* pmd,
TextureRef* ref);
MemoryTypeTracker* GetMemTracker();
std::unique_ptr<MemoryTypeTracker> memory_type_tracker_;
raw_ptr<MemoryTracker> memory_tracker_;
scoped_refptr<FeatureInfo> feature_info_;
std::vector<FramebufferManager*> framebuffer_managers_;
typedef std::unordered_map<GLuint, scoped_refptr<TextureRef>> TextureMap;
TextureMap textures_;
GLsizei max_texture_size_;
GLsizei max_cube_map_texture_size_;
GLsizei max_rectangle_texture_size_;
GLsizei max_3d_texture_size_;
GLsizei max_array_texture_layers_;
GLint max_levels_;
GLint max_cube_map_levels_;
GLint max_3d_levels_;
const bool use_default_textures_;
int num_unsafe_textures_;
int num_uncleared_mips_;
int num_images_;
unsigned int texture_count_;
bool have_context_;
GLuint black_texture_ids_[kNumDefaultTextures];
scoped_refptr<TextureRef> default_textures_[kNumDefaultTextures];
std::vector<DestructionObserver*> destruction_observers_;
uint32_t current_service_id_generation_;
raw_ptr<gl::ProgressReporter> progress_reporter_;
raw_ptr<ServiceDiscardableManager> discardable_manager_;
};
}
}
#endif