| Flutter Impeller |

blit_command_gles.cc
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 #include "impeller/renderer/backend/gles/blit_command_gles.h"
6
7 #include "flutter/fml/closure.h"
8 #include "impeller/base/validation.h"
9 #include "impeller/core/formats.h"
10 #include "impeller/geometry/point.h"
11 #include "impeller/renderer/backend/gles/device_buffer_gles.h"
12 #include "impeller/renderer/backend/gles/formats_gles.h"
13 #include "impeller/renderer/backend/gles/reactor_gles.h"
14 #include "impeller/renderer/backend/gles/texture_gles.h"
15
16 namespace impeller {
17
18 namespace {
19 static void FlipImage(uint8_t* buffer,
20 size_t width,
21 size_t height,
22 size_t stride) {
23 if (buffer == nullptr || stride == 0) {
24 return;
25 }
26
27 const auto byte_width = width * stride;
28
29 for (size_t top = 0; top < height; top++) {
30 size_t bottom = height - top - 1;
31 if (top >= bottom) {
32 break;
33 }
34 auto* top_row = buffer + byte_width * top;
35 auto* bottom_row = buffer + byte_width * bottom;
36 std::swap_ranges(top_row, top_row + byte_width, bottom_row);
37 }
38 }
39 } // namespace
40
41 BlitEncodeGLES::~BlitEncodeGLES() = default;
42
43 static void DeleteFBO(const ProcTableGLES& gl, GLuint fbo, GLenum type) {
44 if (fbo != GL_NONE) {
45 gl.BindFramebuffer(type, GL_NONE);
46 gl.DeleteFramebuffers(1u, &fbo);
47 }
48 };
49
50 static std::optional<GLuint> ConfigureFBO(
51 const ProcTableGLES& gl,
52 const std::shared_ptr<Texture>& texture,
53 GLenum fbo_type) {
54 auto handle = TextureGLES::Cast(texture.get())->GetGLHandle();
55 if (!handle.has_value()) {
56 return std::nullopt;
57 }
58
59 if (TextureGLES::Cast(*texture).IsWrapped()) {
60 // The texture is attached to the default FBO, so there's no need to
61 // create/configure one.
62 gl.BindFramebuffer(fbo_type, 0);
63 return 0;
64 }
65
66 GLuint fbo;
67 gl.GenFramebuffers(1u, &fbo);
68 gl.BindFramebuffer(fbo_type, fbo);
69
70 if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment(
71 fbo_type, TextureGLES::AttachmentType::kColor0)) {
72 VALIDATION_LOG << "Could not attach texture to framebuffer.";
73 DeleteFBO(gl, fbo, fbo_type);
74 return std::nullopt;
75 }
76
77 GLenum status = gl.CheckFramebufferStatus(fbo_type);
78 if (status != GL_FRAMEBUFFER_COMPLETE) {
79 VALIDATION_LOG << "Could not create a complete framebuffer: "
80 << DebugToFramebufferError(status);
81 DeleteFBO(gl, fbo, fbo_type);
82 return std::nullopt;
83 }
84
85 return fbo;
86 };
87
88 BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES() =
89 default;
90
91 std::string BlitCopyTextureToTextureCommandGLES::GetLabel() const {
92 return label;
93 }
94
95 bool BlitCopyTextureToTextureCommandGLES::Encode(
96 const ReactorGLES& reactor) const {
97 const auto& gl = reactor.GetProcTable();
98
99 // glBlitFramebuffer is a GLES3 proc. Since we target GLES2, we need to
100 // emulate the blit when it's not available in the driver.
101 if (!gl.BlitFramebuffer.IsAvailable()) {
102 // TODO(157064): Emulate the blit using a raster draw call here.
103 VALIDATION_LOG << "Texture blit fallback not implemented yet for GLES2.";
104 return false;
105 }
106
107 GLuint read_fbo = GL_NONE;
108 GLuint draw_fbo = GL_NONE;
109 fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {
110 DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER);
111 DeleteFBO(gl, draw_fbo, GL_DRAW_FRAMEBUFFER);
112 });
113
114 {
115 auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
116 if (!read.has_value()) {
117 return false;
118 }
119 read_fbo = read.value();
120 }
121
122 {
123 auto draw = ConfigureFBO(gl, destination, GL_DRAW_FRAMEBUFFER);
124 if (!draw.has_value()) {
125 return false;
126 }
127 draw_fbo = draw.value();
128 }
129
130 gl.Disable(GL_SCISSOR_TEST);
131 gl.Disable(GL_DEPTH_TEST);
132 gl.Disable(GL_STENCIL_TEST);
133
134 gl.BlitFramebuffer(source_region.GetX(), // srcX0
135 source_region.GetY(), // srcY0
136 source_region.GetWidth(), // srcX1
137 source_region.GetHeight(), // srcY1
138 destination_origin.x, // dstX0
139 destination_origin.y, // dstY0
140 source_region.GetWidth(), // dstX1
141 source_region.GetHeight(), // dstY1
142 GL_COLOR_BUFFER_BIT, // mask
143 GL_NEAREST // filter
144 );
145
146 return true;
147 };
148
149 namespace {
150 struct TexImage2DData {
151 GLint internal_format = 0;
152 GLenum external_format = GL_NONE;
153 GLenum type = GL_NONE;
154 BufferView buffer_view;
155
156 explicit TexImage2DData(PixelFormat pixel_format) {
157 switch (pixel_format) {
158 case PixelFormat::kA8UNormInt:
159 internal_format = GL_ALPHA;
160 external_format = GL_ALPHA;
161 type = GL_UNSIGNED_BYTE;
162 break;
163 case PixelFormat::kR8UNormInt:
164 internal_format = GL_RED;
165 external_format = GL_RED;
166 type = GL_UNSIGNED_BYTE;
167 break;
168 case PixelFormat::kR8G8B8A8UNormInt:
169 case PixelFormat::kB8G8R8A8UNormInt:
170 case PixelFormat::kR8G8B8A8UNormIntSRGB:
171 case PixelFormat::kB8G8R8A8UNormIntSRGB:
172 internal_format = GL_RGBA;
173 external_format = GL_RGBA;
174 type = GL_UNSIGNED_BYTE;
175 break;
176 case PixelFormat::kR32G32B32A32Float:
177 internal_format = GL_RGBA;
178 external_format = GL_RGBA;
179 type = GL_FLOAT;
180 break;
181 case PixelFormat::kR32Float:
182 internal_format = GL_RED;
183 external_format = GL_RED;
184 type = GL_FLOAT;
185 break;
186 case PixelFormat::kR16G16B16A16Float:
187 internal_format = GL_RGBA;
188 external_format = GL_RGBA;
189 type = GL_HALF_FLOAT;
190 break;
191 case PixelFormat::kS8UInt:
192 // Pure stencil textures are only available in OpenGL 4.4+, which is
193 // ~0% of mobile devices. Instead, we use a depth-stencil texture and
194 // only use the stencil component.
195 //
196 // https://registry.khronos.org/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
197 case PixelFormat::kD24UnormS8Uint:
198 internal_format = GL_DEPTH_STENCIL;
199 external_format = GL_DEPTH_STENCIL;
200 type = GL_UNSIGNED_INT_24_8;
201 break;
202 case PixelFormat::kUnknown:
203 case PixelFormat::kD32FloatS8UInt:
204 case PixelFormat::kR8G8UNormInt:
205 case PixelFormat::kB10G10R10XRSRGB:
206 case PixelFormat::kB10G10R10XR:
207 case PixelFormat::kB10G10R10A10XR:
208 return;
209 }
210 is_valid_ = true;
211 }
212
213 TexImage2DData(PixelFormat pixel_format, BufferView p_buffer_view)
214 : TexImage2DData(pixel_format) {
215 buffer_view = std::move(p_buffer_view);
216 }
217
218 bool IsValid() const { return is_valid_; }
219
220 private:
221 bool is_valid_ = false;
222 };
223 } // namespace
224
225 BlitCopyBufferToTextureCommandGLES::~BlitCopyBufferToTextureCommandGLES() =
226 default;
227
228 std::string BlitCopyBufferToTextureCommandGLES::GetLabel() const {
229 return label;
230 }
231
232 bool BlitCopyBufferToTextureCommandGLES::Encode(
233 const ReactorGLES& reactor) const {
234 TextureGLES& texture_gles = TextureGLES::Cast(*destination);
235
236 if (texture_gles.GetType() != TextureGLES::Type::kTexture) {
237 VALIDATION_LOG << "Incorrect texture usage flags for setting contents on "
238 "this texture object.";
239 return false;
240 }
241
242 if (texture_gles.IsWrapped()) {
243 VALIDATION_LOG << "Cannot set the contents of a wrapped texture.";
244 return false;
245 }
246
247 const auto& tex_descriptor = texture_gles.GetTextureDescriptor();
248
249 if (tex_descriptor.size.IsEmpty()) {
250 return true;
251 }
252
253 if (!tex_descriptor.IsValid() ||
254 source.GetRange().length !=
255 BytesPerPixelForPixelFormat(tex_descriptor.format) *
256 destination_region.Area()) {
257 return false;
258 }
259
260 destination->SetCoordinateSystem(TextureCoordinateSystem::kUploadFromHost);
261
262 GLenum texture_type;
263 GLenum texture_target;
264 switch (tex_descriptor.type) {
265 case TextureType::kTexture2D:
266 texture_type = GL_TEXTURE_2D;
267 texture_target = GL_TEXTURE_2D;
268 break;
269 case TextureType::kTexture2DMultisample:
270 VALIDATION_LOG << "Multisample texture uploading is not supported for "
271 "the OpenGLES backend.";
272 return false;
273 case TextureType::kTextureCube:
274 texture_type = GL_TEXTURE_CUBE_MAP;
275 texture_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
276 break;
277 case TextureType::kTextureExternalOES:
278 texture_type = GL_TEXTURE_EXTERNAL_OES;
279 texture_target = GL_TEXTURE_EXTERNAL_OES;
280 break;
281 }
282
283 TexImage2DData data = TexImage2DData(tex_descriptor.format, source);
284 if (!data.IsValid()) {
285 VALIDATION_LOG << "Invalid texture format.";
286 return false;
287 }
288
289 auto gl_handle = texture_gles.GetGLHandle();
290 if (!gl_handle.has_value()) {
291 VALIDATION_LOG
292 << "Texture was collected before it could be uploaded to the GPU.";
293 return false;
294 }
295 const auto& gl = reactor.GetProcTable();
296 gl.BindTexture(texture_type, gl_handle.value());
297 const GLvoid* tex_data = data.buffer_view.GetBuffer()->OnGetContents() +
298 data.buffer_view.GetRange().offset;
299
300 // GL_INVALID_OPERATION if the texture array has not been
301 // defined by a previous glTexImage2D operation.
302 if (!texture_gles.IsSliceInitialized(slice)) {
303 gl.TexImage2D(texture_target, // target
304 mip_level, // LOD level
305 data.internal_format, // internal format
306 tex_descriptor.size.width, // width
307 tex_descriptor.size.height, // height
308 0u, // border
309 data.external_format, // external format
310 data.type, // type
311 nullptr // data
312 );
313 texture_gles.MarkSliceInitialized(slice);
314 }
315
316 {
317 gl.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
318 gl.TexSubImage2D(texture_target, // target
319 mip_level, // LOD level
320 destination_region.GetX(), // xoffset
321 destination_region.GetY(), // yoffset
322 destination_region.GetWidth(), // width
323 destination_region.GetHeight(), // height
324 data.external_format, // external format
325 data.type, // type
326 tex_data // data
327
328 );
329 }
330 return true;
331 }
332
333 BlitCopyTextureToBufferCommandGLES::~BlitCopyTextureToBufferCommandGLES() =
334 default;
335
336 std::string BlitCopyTextureToBufferCommandGLES::GetLabel() const {
337 return label;
338 }
339
340 bool BlitCopyTextureToBufferCommandGLES::Encode(
341 const ReactorGLES& reactor) const {
342 if (source->GetTextureDescriptor().format != PixelFormat::kR8G8B8A8UNormInt) {
343 VALIDATION_LOG << "Only textures with pixel format RGBA are supported yet.";
344 return false;
345 }
346
347 const auto& gl = reactor.GetProcTable();
348 TextureCoordinateSystem coord_system = source->GetCoordinateSystem();
349
350 GLuint read_fbo = GL_NONE;
351 fml::ScopedCleanupClosure delete_fbos(
352 [&gl, &read_fbo]() { DeleteFBO(gl, read_fbo, GL_FRAMEBUFFER); });
353
354 {
355 auto read = ConfigureFBO(gl, source, GL_FRAMEBUFFER);
356 if (!read.has_value()) {
357 return false;
358 }
359 read_fbo = read.value();
360 }
361
362 DeviceBufferGLES::Cast(*destination)
363 .UpdateBufferData([&gl, this, coord_system,
364 rows = source->GetSize().height](uint8_t* data,
365
366 size_t length) {
367 gl.ReadPixels(source_region.GetX(), source_region.GetY(),
368 source_region.GetWidth(), source_region.GetHeight(),
369 GL_RGBA, GL_UNSIGNED_BYTE, data + destination_offset);
370 switch (coord_system) {
371 case TextureCoordinateSystem::kUploadFromHost:
372 break;
373 case TextureCoordinateSystem::kRenderToTexture:
374 // The texture is upside down, and must be inverted when copying
375 // byte data out.
376 FlipImage(data + destination_offset, source_region.GetWidth(),
377 source_region.GetHeight(), 4);
378 }
379 });
380
381 return true;
382 };
383
384 BlitGenerateMipmapCommandGLES::~BlitGenerateMipmapCommandGLES() = default;
385
386 std::string BlitGenerateMipmapCommandGLES::GetLabel() const {
387 return label;
388 }
389
390 bool BlitGenerateMipmapCommandGLES::Encode(const ReactorGLES& reactor) const {
391 auto texture_gles = TextureGLES::Cast(texture.get());
392 if (!texture_gles->GenerateMipmap()) {
393 return false;
394 }
395
396 return true;
397 };
398
399 ////// BlitResizeTextureCommandGLES
400 //////////////////////////////////////////////////////
401
402 BlitResizeTextureCommandGLES::~BlitResizeTextureCommandGLES() = default;
403
404 std::string BlitResizeTextureCommandGLES::GetLabel() const {
405 return "Resize Texture";
406 }
407
408 bool BlitResizeTextureCommandGLES::Encode(const ReactorGLES& reactor) const {
409 const auto& gl = reactor.GetProcTable();
410
411 // glBlitFramebuffer is a GLES3 proc. Since we target GLES2, we need to
412 // emulate the blit when it's not available in the driver.
413 if (!gl.BlitFramebuffer.IsAvailable()) {
414 // TODO(157064): Emulate the blit using a raster draw call here.
415 VALIDATION_LOG << "Texture blit fallback not implemented yet for GLES2.";
416 return false;
417 }
418
419 destination->SetCoordinateSystem(source->GetCoordinateSystem());
420
421 GLuint read_fbo = GL_NONE;
422 GLuint draw_fbo = GL_NONE;
423 fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {
424 DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER);
425 DeleteFBO(gl, draw_fbo, GL_DRAW_FRAMEBUFFER);
426 });
427
428 {
429 auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
430 if (!read.has_value()) {
431 return false;
432 }
433 read_fbo = read.value();
434 }
435
436 {
437 auto draw = ConfigureFBO(gl, destination, GL_DRAW_FRAMEBUFFER);
438 if (!draw.has_value()) {
439 return false;
440 }
441 draw_fbo = draw.value();
442 }
443
444 gl.Disable(GL_SCISSOR_TEST);
445 gl.Disable(GL_DEPTH_TEST);
446 gl.Disable(GL_STENCIL_TEST);
447
448 const IRect source_region = IRect::MakeSize(source->GetSize());
449 const IRect destination_region = IRect::MakeSize(destination->GetSize());
450
451 gl.BlitFramebuffer(source_region.GetX(), // srcX0
452 source_region.GetY(), // srcY0
453 source_region.GetWidth(), // srcX1
454 source_region.GetHeight(), // srcY1
455 destination_region.GetX(), // dstX0
456 destination_region.GetY(), // dstY0
457 destination_region.GetWidth(), // dstX1
458 destination_region.GetHeight(), // dstY1
459 GL_COLOR_BUFFER_BIT, // mask
460 GL_LINEAR // filter
461 );
462
463 return true;
464 }
465
466 } // namespace impeller
type
GLenum type
Definition: blit_command_gles.cc:153
external_format
GLenum external_format
Definition: blit_command_gles.cc:152
internal_format
GLint internal_format
Definition: blit_command_gles.cc:151
buffer_view
BufferView buffer_view
Definition: blit_command_gles.cc:154
blit_command_gles.h
impeller::BackendCast< TextureGLES, Texture >::Cast
static TextureGLES & Cast(Texture &base)
Definition: backend_cast.h:13
impeller::DeviceBufferGLES::UpdateBufferData
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
Definition: device_buffer_gles.cc:151
impeller::ProcTableGLES
Definition: proc_table_gles.h:283
impeller::ReactorGLES
The reactor attempts to make thread-safe usage of OpenGL ES easier to reason about.
Definition: reactor_gles.h:57
impeller::ReactorGLES::GetProcTable
const ProcTableGLES & GetProcTable() const
Get the OpenGL proc. table the reactor uses to manage handles.
Definition: reactor_gles.cc:122
impeller::TextureGLES
Definition: texture_gles.h:19
impeller::TextureGLES::IsSliceInitialized
bool IsSliceInitialized(size_t slice) const
Definition: texture_gles.cc:567
impeller::TextureGLES::Type::kTexture
@ kTexture
impeller::TextureGLES::AttachmentType::kColor0
@ kColor0
impeller::TextureGLES::GetType
Type GetType() const
Definition: texture_gles.cc:605
impeller::TextureGLES::SetAsFramebufferAttachment
bool SetAsFramebufferAttachment(GLenum target, AttachmentType attachment_type) const
Definition: texture_gles.cc:620
impeller::TextureGLES::MarkSliceInitialized
void MarkSliceInitialized(size_t slice) const
Indicates that a specific texture slice has been initialized.
Definition: texture_gles.cc:563
impeller::TextureGLES::GetGLHandle
std::optional< GLuint > GetGLHandle() const
Definition: texture_gles.cc:515
impeller::TextureGLES::IsWrapped
bool IsWrapped() const
Definition: texture_gles.cc:677
impeller::Texture::GetTextureDescriptor
const TextureDescriptor & GetTextureDescriptor() const
Definition: texture.cc:57
formats.h
device_buffer_gles.h
formats_gles.h
impeller
Definition: allocation.cc:12
impeller::BytesPerPixelForPixelFormat
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:469
impeller::ConfigureFBO
static std::optional< GLuint > ConfigureFBO(const ProcTableGLES &gl, const std::shared_ptr< Texture > &texture, GLenum fbo_type)
Definition: blit_command_gles.cc:50
impeller::DebugToFramebufferError
std::string DebugToFramebufferError(int status)
Definition: formats_gles.cc:9
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::PixelFormat::kR8G8B8A8UNormIntSRGB
@ kR8G8B8A8UNormIntSRGB
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt
impeller::PixelFormat::kUnknown
@ kUnknown
impeller::PixelFormat::kR32G32B32A32Float
@ kR32G32B32A32Float
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::PixelFormat::kB10G10R10XRSRGB
@ kB10G10R10XRSRGB
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
impeller::PixelFormat::kR8G8UNormInt
@ kR8G8UNormInt
impeller::PixelFormat::kB8G8R8A8UNormIntSRGB
@ kB8G8R8A8UNormIntSRGB
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::PixelFormat::kR32Float
@ kR32Float
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::DeleteFBO
static void DeleteFBO(const ProcTableGLES &gl, GLuint fbo, GLenum type)
Definition: blit_command_gles.cc:43
impeller::TextureType::kTextureExternalOES
@ kTextureExternalOES
impeller::TextureType::kTexture2DMultisample
@ kTexture2DMultisample
impeller::TextureType::kTexture2D
@ kTexture2D
impeller::TextureType::kTextureCube
@ kTextureCube
impeller::TextureCoordinateSystem
TextureCoordinateSystem
Definition: formats.h:330
impeller::TextureCoordinateSystem::kUploadFromHost
@ kUploadFromHost
point.h
reactor_gles.h
impeller::BlitCommand::label
std::string label
Definition: blit_command.h:16
impeller::BlitCopyBufferToTextureCommandGLES::~BlitCopyBufferToTextureCommandGLES
~BlitCopyBufferToTextureCommandGLES() override
impeller::BlitCopyBufferToTextureCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:228
impeller::BlitCopyBufferToTextureCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:232
impeller::BlitCopyBufferToTextureCommand::mip_level
uint32_t mip_level
Definition: blit_command.h:42
impeller::BlitCopyBufferToTextureCommand::slice
uint32_t slice
Definition: blit_command.h:43
impeller::BlitCopyBufferToTextureCommand::destination
std::shared_ptr< Texture > destination
Definition: blit_command.h:40
impeller::BlitCopyBufferToTextureCommand::source
BufferView source
Definition: blit_command.h:39
impeller::BlitCopyBufferToTextureCommand::destination_region
IRect destination_region
Definition: blit_command.h:41
impeller::BlitCopyTextureToBufferCommandGLES::~BlitCopyTextureToBufferCommandGLES
~BlitCopyTextureToBufferCommandGLES() override
impeller::BlitCopyTextureToBufferCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:340
impeller::BlitCopyTextureToBufferCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:336
impeller::BlitCopyTextureToBufferCommand::destination
std::shared_ptr< DeviceBuffer > destination
Definition: blit_command.h:33
impeller::BlitCopyTextureToBufferCommand::source
std::shared_ptr< Texture > source
Definition: blit_command.h:32
impeller::BlitCopyTextureToTextureCommandGLES::Encode
bool Encode(const ReactorGLES &reactor) const override
Definition: blit_command_gles.cc:95
impeller::BlitCopyTextureToTextureCommandGLES::GetLabel
std::string GetLabel() const override
Definition: blit_command_gles.cc:91
impeller::BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES
~BlitCopyTextureToTextureCommandGLES() override
impeller::BlitCopyTextureToTextureCommand::destination_origin
IPoint destination_origin
Definition: blit_command.h:23
impeller::BlitCopyTextureToTextureCommand::destination
std::shared_ptr< Texture > destination
Definition: blit_command.h:21
impeller::BlitCopyTextureToTextureCommand::source_region
IRect source_region
Definition: blit_command.h:22
impeller::BlitCopyTextureToTextureCommand::source
std::shared_ptr< Texture > source
Definition: blit_command.h:20
impeller::BlitEncodeGLES::~BlitEncodeGLES
virtual ~BlitEncodeGLES()
impeller::BufferView::GetRange
Range GetRange() const
Definition: buffer_view.h:27
impeller::Range::length
size_t length
Definition: range.h:15
impeller::TPoint::y
Type y
Definition: point.h:32
impeller::TPoint::x
Type x
Definition: point.h:31
impeller::TRect
Definition: rect.h:122
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:337
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:347
impeller::TRect::Area
constexpr T Area() const
Get the area of the rectangle, equivalent to |GetSize().Area()|.
Definition: rect.h:376
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:333
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:341
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:69
texture_gles.h
validation.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91