Flutter Impeller
blit_pass.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 
6 #include <memory>
7 #include <utility>
8 
11 #include "impeller/core/formats.h"
14 
15 namespace impeller {
16 
17 BlitPass::BlitPass() : transients_buffer_(HostBuffer::Create()) {}
18 
19 BlitPass::~BlitPass() = default;
20 
22  return *transients_buffer_;
23 }
24 
25 void BlitPass::SetLabel(std::string label) {
26  if (label.empty()) {
27  return;
28  }
29  transients_buffer_->SetLabel(SPrintF("%s Transients", label.c_str()));
30  OnSetLabel(std::move(label));
31 }
32 
33 bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
34  std::shared_ptr<Texture> destination,
35  std::optional<IRect> source_region,
36  IPoint destination_origin,
37  std::string label) {
38  if (!source) {
39  VALIDATION_LOG << "Attempted to add a texture blit with no source.";
40  return false;
41  }
42  if (!destination) {
43  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
44  return false;
45  }
46 
47  if (source->GetTextureDescriptor().sample_count !=
48  destination->GetTextureDescriptor().sample_count) {
50  "The source sample count (%d) must match the destination sample count "
51  "(%d) for blits.",
52  static_cast<int>(source->GetTextureDescriptor().sample_count),
53  static_cast<int>(destination->GetTextureDescriptor().sample_count));
54  return false;
55  }
56  if (source->GetTextureDescriptor().format !=
57  destination->GetTextureDescriptor().format) {
59  "The source pixel format (%s) must match the destination pixel format "
60  "(%s) "
61  "for blits.",
62  PixelFormatToString(source->GetTextureDescriptor().format),
63  PixelFormatToString(destination->GetTextureDescriptor().format));
64  return false;
65  }
66 
67  if (!source_region.has_value()) {
68  source_region = IRect::MakeSize(source->GetSize());
69  }
70 
71  // Clip the source image.
72  source_region =
73  source_region->Intersection(IRect::MakeSize(source->GetSize()));
74  if (!source_region.has_value()) {
75  return true; // Nothing to blit.
76  }
77 
78  // Clip the destination image.
79  source_region = source_region->Intersection(
80  IRect::MakeOriginSize(-destination_origin, destination->GetSize()));
81  if (!source_region.has_value()) {
82  return true; // Nothing to blit.
83  }
84 
86  std::move(source), std::move(destination), source_region.value(),
87  destination_origin, std::move(label));
88 }
89 
90 bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
91  std::shared_ptr<DeviceBuffer> destination,
92  std::optional<IRect> source_region,
93  size_t destination_offset,
94  std::string label) {
95  if (!source) {
96  VALIDATION_LOG << "Attempted to add a texture blit with no source.";
97  return false;
98  }
99  if (!destination) {
100  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
101  return false;
102  }
103 
104  if (!source_region.has_value()) {
105  source_region = IRect::MakeSize(source->GetSize());
106  }
107 
108  auto bytes_per_pixel =
109  BytesPerPixelForPixelFormat(source->GetTextureDescriptor().format);
110  auto bytes_per_image = source_region->Area() * bytes_per_pixel;
111  if (destination_offset + bytes_per_image >
112  destination->GetDeviceBufferDescriptor().size) {
114  << "Attempted to add a texture blit with out of bounds access.";
115  return false;
116  }
117 
118  // Clip the source image.
119  source_region =
120  source_region->Intersection(IRect::MakeSize(source->GetSize()));
121  if (!source_region.has_value()) {
122  return true; // Nothing to blit.
123  }
124 
125  return OnCopyTextureToBufferCommand(std::move(source), std::move(destination),
126  source_region.value(), destination_offset,
127  std::move(label));
128 }
129 
131  std::shared_ptr<Texture> destination,
132  IPoint destination_origin,
133  std::string label) {
134  if (!destination) {
135  VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
136  return false;
137  }
138 
139  auto bytes_per_pixel =
140  BytesPerPixelForPixelFormat(destination->GetTextureDescriptor().format);
141  auto bytes_per_image =
142  destination->GetTextureDescriptor().size.Area() * bytes_per_pixel;
143 
144  if (source.range.length != bytes_per_image) {
146  << "Attempted to add a texture blit with out of bounds access.";
147  return false;
148  }
149 
150  return OnCopyBufferToTextureCommand(std::move(source), std::move(destination),
151  destination_origin, std::move(label));
152 }
153 
154 bool BlitPass::GenerateMipmap(std::shared_ptr<Texture> texture,
155  std::string label) {
156  if (!texture) {
157  VALIDATION_LOG << "Attempted to add an invalid mipmap generation command "
158  "with no texture.";
159  return false;
160  }
161 
162  return OnGenerateMipmapCommand(std::move(texture), std::move(label));
163 }
164 
165 } // namespace impeller
impeller::BlitPass::OnCopyTextureToBufferCommand
virtual bool OnCopyTextureToBufferCommand(std::shared_ptr< Texture > source, std::shared_ptr< DeviceBuffer > destination, IRect source_region, size_t destination_offset, std::string label)=0
host_buffer.h
impeller::PixelFormatToString
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:135
impeller::HostBuffer
Definition: host_buffer.h:20
blit_command.h
formats.h
impeller::BlitPass::~BlitPass
virtual ~BlitPass()
impeller::BlitPass::AddCopy
bool AddCopy(std::shared_ptr< Texture > source, std::shared_ptr< Texture > destination, std::optional< IRect > source_region=std::nullopt, IPoint destination_origin={}, std::string label="")
Record a command to copy the contents of one texture to another texture. The blit area is limited by ...
Definition: blit_pass.cc:33
impeller::BlitPass::BlitPass
BlitPass()
Definition: blit_pass.cc:17
impeller::BufferView::range
Range range
Definition: buffer_view.h:16
impeller::BlitPass::GenerateMipmap
bool GenerateMipmap(std::shared_ptr< Texture > texture, std::string label="")
Record a command to generate all mip levels for a texture. No work is encoded into the command buffer...
Definition: blit_pass.cc:154
impeller::BlitPass::OnCopyTextureToTextureCommand
virtual bool OnCopyTextureToTextureCommand(std::shared_ptr< Texture > source, std::shared_ptr< Texture > destination, IRect source_region, IPoint destination_origin, std::string label)=0
validation.h
impeller::BlitPass::OnCopyBufferToTextureCommand
virtual bool OnCopyBufferToTextureCommand(BufferView source, std::shared_ptr< Texture > destination, IPoint destination_origin, std::string label)=0
impeller::BytesPerPixelForPixelFormat
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:442
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::TRect< int64_t >::MakeOriginSize
constexpr static TRect MakeOriginSize(const TPoint< Type > &origin, const TSize< Type > &size)
Definition: rect.h:38
impeller::BlitPass::GetTransientsBuffer
HostBuffer & GetTransientsBuffer()
Definition: blit_pass.cc:21
blit_pass.h
impeller::BlitPass::OnGenerateMipmapCommand
virtual bool OnGenerateMipmapCommand(std::shared_ptr< Texture > texture, std::string label)=0
impeller::BlitPass::OnSetLabel
virtual void OnSetLabel(std::string label)=0
strings.h
impeller::BlitPass::SetLabel
void SetLabel(std::string label)
Definition: blit_pass.cc:25
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::BufferView
Definition: buffer_view.h:13
impeller::BlitPass::transients_buffer_
std::shared_ptr< HostBuffer > transients_buffer_
Definition: blit_pass.h:131
impeller::TRect< int64_t >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:44
impeller::TPoint< int64_t >
impeller::Range::length
size_t length
Definition: range.h:16
impeller
Definition: aiks_context.cc:10