Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
texture_gles.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_TEXTURE_GLES_H_
6#define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_TEXTURE_GLES_H_
7
8#include <array>
9#include <bitset>
10
11#include "fml/logging.h"
17
18namespace impeller {
19
20class TextureGLES final : public Texture,
21 public BackendCast<TextureGLES, Texture> {
22 public:
29
30 //----------------------------------------------------------------------------
31 /// @brief Create a texture by wrapping an external framebuffer object
32 /// whose lifecycle is owned by the caller.
33 ///
34 /// This is useful for creating a render target for the default
35 /// window managed framebuffer.
36 ///
37 /// @param[in] reactor The reactor
38 /// @param[in] desc The description
39 /// @param[in] fbo The fbo
40 ///
41 /// @return If a texture representation of the framebuffer could be
42 /// created.
43 ///
44 static std::shared_ptr<TextureGLES> WrapFBO(
45 std::shared_ptr<ReactorGLES> reactor,
47 GLuint fbo);
48
49 //----------------------------------------------------------------------------
50 /// @brief Create a texture by wrapping an external OpenGL texture
51 /// handle. Ownership of the texture handle is assumed by the
52 /// reactor.
53 ///
54 /// @param[in] reactor The reactor
55 /// @param[in] desc The description
56 /// @param[in] external_handle The external handle
57 ///
58 /// @return If a texture representation of the framebuffer could be
59 /// created.
60 ///
61 static std::shared_ptr<TextureGLES> WrapTexture(
62 std::shared_ptr<ReactorGLES> reactor,
64 HandleGLES external_handle);
65
66 //----------------------------------------------------------------------------
67 /// @brief Create a "texture" that is never expected to be bound/unbound
68 /// explicitly or initialized in any way. It only exists to setup
69 /// a render pass description.
70 ///
71 /// @param[in] reactor The reactor
72 /// @param[in] desc The description
73 ///
74 /// @return If a texture placeholder could be created.
75 ///
76 static std::shared_ptr<TextureGLES> CreatePlaceholder(
77 std::shared_ptr<ReactorGLES> reactor,
79
80 TextureGLES(std::shared_ptr<ReactorGLES> reactor,
82 bool threadsafe = false);
83
84 // |Texture|
85 bool IsValid() const override;
86
87 std::optional<GLuint> GetGLHandle() const;
88
89 [[nodiscard]] bool Bind();
90
91 [[nodiscard]] bool GenerateMipmap();
92
93 enum class AttachmentType {
94 kColor0,
95 kDepth,
97 };
98 [[nodiscard]] bool SetAsFramebufferAttachment(GLenum target,
99 AttachmentType attachment_type,
100 uint32_t mip_level = 0,
101 uint32_t slice = 0);
102
103 Type GetType() const;
104
105 bool IsWrapped() const;
106
107 /// @brief Reset the internal texture state so that the reactor will not free
108 /// the associated handle.
109 void Leak();
110
111 std::optional<GLuint> GetFBO() const;
112
113 //----------------------------------------------------------------------------
114 /// @brief Indicates that all texture storage has already been allocated
115 /// and contents initialized.
116 ///
117 /// This is similar to calling `MarkSliceInitialized` with all
118 /// slices.
119 ///
120 /// @see MarkSliceInitialized.
121 ///
123
124 //----------------------------------------------------------------------------
125 /// @brief Indicates that a specific texture slice has been initialized.
126 ///
127 /// @param[in] slice The slice to mark as being initialized.
128 ///
129 void MarkSliceInitialized(size_t slice);
130
131 bool IsSliceInitialized(size_t slice) const;
132
133 //----------------------------------------------------------------------------
134 /// @brief Indicates that storage for `mip_level` of `slice` has been
135 /// allocated by a `glTexImage2D` call (or equivalent).
136 ///
137 /// GLES raises `GL_INVALID_OPERATION` when `glTexSubImage2D`
138 /// targets a level that has not been previously defined, so
139 /// every per-level upload must check this first and allocate
140 /// on demand.
141 ///
142 /// @param[in] slice The slice (cubemap face for cubemaps, otherwise
143 /// always 0).
144 /// @param[in] mip_level The mip level whose storage was allocated.
145 ///
146 void MarkSliceMipLevelInitialized(size_t slice, size_t mip_level);
147
148 bool IsSliceMipLevelInitialized(size_t slice, size_t mip_level) const;
149
150 //----------------------------------------------------------------------------
151 /// @brief Attach a sync fence to this texture that will be waited on
152 /// before encoding a rendering operation that references it.
153 ///
154 /// @param[in] fence A handle to a sync fence.
155 ///
156 void SetFence(HandleGLES fence);
157
158 /// Store the FBO object for recycling in the 2D renderer.
159 ///
160 /// The color0 texture used by the 2D renderer will use this texture
161 /// object to store the associated FBO the first time it is used.
162 void SetCachedFBO(HandleGLES fbo);
163
164 /// Retrieve the cached FBO object, or a dead handle if there is no object.
165 const HandleGLES& GetCachedFBO() const;
166
167 /// Records the subresource the cached FBO is currently bound to.
168 void SetCachedFBOSubresource(uint32_t mip_level, uint32_t slice);
169
170 /// Whether the cached FBO is currently bound to `(mip_level, slice)`. When
171 /// false, the FBO must be re-attached before use.
172 bool CachedFBOMatchesSubresource(uint32_t mip_level, uint32_t slice) const;
173
174 // Visible for testing.
175 std::optional<HandleGLES> GetSyncFence() const;
176
177 // visible for testing
178 Type ComputeTypeForBinding(GLenum target) const;
179
180 private:
181 std::shared_ptr<ReactorGLES> reactor_;
182 const Type type_;
183 UniqueHandleGLES handle_;
184 UniqueHandleGLES fence_;
185 // Tracks which `(slice, mip_level)` pairs have had their storage allocated
186 // by a `glTexImage2D` call. Allocation is performed lazily on first write
187 // to a level so the only-renders-then-mipmaps path (Impeller's snapshot
188 // pipeline) keeps its single base-level allocation, and per-level uploads
189 // only pay for the levels they actually touch.
190 //
191 // Sized for up to 6 cubemap faces × 16 mip levels (covers a 32k base
192 // dimension); requested levels above this are simply not tracked.
193 static constexpr size_t kMaxTrackedMipLevels = 16;
194 std::array<std::bitset<kMaxTrackedMipLevels>, 6> slice_mip_initialized_ = {};
195 const bool is_wrapped_;
196 const std::optional<GLuint> wrapped_fbo_;
197 UniqueHandleGLES cached_fbo_;
198 uint32_t cached_fbo_mip_level_ = 0;
199 uint32_t cached_fbo_slice_ = 0;
200 bool is_valid_ = false;
201
202 TextureGLES(std::shared_ptr<ReactorGLES> reactor,
203 TextureDescriptor desc,
204 bool threadsafe,
205 std::optional<GLuint> fbo,
206 std::optional<HandleGLES> external_handle);
207
208 // |Texture|
209 void SetLabel(std::string_view label) override;
210
211 // |Texture|
212 void SetLabel(std::string_view label, std::string_view trailing) override;
213
214 // |Texture|
215 bool OnSetContents(const uint8_t* contents,
216 size_t length,
217 size_t slice) override;
218
219 // |Texture|
220 bool OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
221 size_t slice) override;
222
223 // |Texture|
224 ISize GetSize() const override;
225
226 void InitializeContentsIfNecessary();
227
228 // Allocates storage for `(slice, mip_level)` if it has not been allocated
229 // yet, so the subresource can be attached to a framebuffer. Returns false on
230 // failure.
231 bool EnsureSliceMipLevelStorage(size_t slice, size_t mip_level);
232
233 TextureGLES(const TextureGLES&) = delete;
234
235 TextureGLES& operator=(const TextureGLES&) = delete;
236};
237
238} // namespace impeller
239
240#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_TEXTURE_GLES_H_
Represents a handle to an underlying OpenGL object. Unlike OpenGL object handles, these handles can b...
Definition handle_gles.h:42
void MarkSliceInitialized(size_t slice)
Indicates that a specific texture slice has been initialized.
static std::shared_ptr< TextureGLES > WrapFBO(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, GLuint fbo)
Create a texture by wrapping an external framebuffer object whose lifecycle is owned by the caller.
void MarkContentsInitialized()
Indicates that all texture storage has already been allocated and contents initialized.
const HandleGLES & GetCachedFBO() const
Retrieve the cached FBO object, or a dead handle if there is no object.
std::optional< HandleGLES > GetSyncFence() const
bool IsSliceMipLevelInitialized(size_t slice, size_t mip_level) const
bool CachedFBOMatchesSubresource(uint32_t mip_level, uint32_t slice) const
bool IsSliceInitialized(size_t slice) const
void SetCachedFBOSubresource(uint32_t mip_level, uint32_t slice)
Records the subresource the cached FBO is currently bound to.
void MarkSliceMipLevelInitialized(size_t slice, size_t mip_level)
Indicates that storage for mip_level of slice has been allocated by a glTexImage2D call (or equivalen...
bool IsValid() const override
void SetFence(HandleGLES fence)
Attach a sync fence to this texture that will be waited on before encoding a rendering operation that...
void Leak()
Reset the internal texture state so that the reactor will not free the associated handle.
void SetCachedFBO(HandleGLES fbo)
static std::shared_ptr< TextureGLES > CreatePlaceholder(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc)
Create a "texture" that is never expected to be bound/unbound explicitly or initialized in any way....
bool SetAsFramebufferAttachment(GLenum target, AttachmentType attachment_type, uint32_t mip_level=0, uint32_t slice=0)
std::optional< GLuint > GetFBO() const
Type ComputeTypeForBinding(GLenum target) const
std::optional< GLuint > GetGLHandle() const
static std::shared_ptr< TextureGLES > WrapTexture(std::shared_ptr< ReactorGLES > reactor, TextureDescriptor desc, HandleGLES external_handle)
Create a texture by wrapping an external OpenGL texture handle. Ownership of the texture handle is as...
A unique handle to an OpenGL object. The collection of this handle scheduled the destruction of the a...
uint32_t * target
size_t length
ISize64 ISize
Definition size.h:162
std::shared_ptr< ReactorGLES > reactor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...