Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
fragment_shader.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 <memory>
6#include <utility>
7
9
15
16namespace flutter {
17
19
20ReusableFragmentShader::ReusableFragmentShader(
22 uint64_t float_count,
23 uint64_t sampler_count)
24 : program_(std::move(program)),
25 uniform_data_(SkData::MakeUninitialized(
26 (float_count + 2 * sampler_count) * sizeof(float))),
27 samplers_(sampler_count),
28 float_count_(float_count) {}
29
30Dart_Handle ReusableFragmentShader::Create(Dart_Handle wrapper,
31 Dart_Handle program,
32 Dart_Handle float_count_handle,
33 Dart_Handle sampler_count_handle) {
34 auto* fragment_program =
36 uint64_t float_count =
38 uint64_t sampler_count =
39 tonic::DartConverter<uint64_t>::FromDart(sampler_count_handle);
40
41 auto res = fml::MakeRefCounted<ReusableFragmentShader>(
42 fml::Ref(fragment_program), float_count, sampler_count);
43 res->AssociateWithDartWrapper(wrapper);
44
45 void* raw_uniform_data =
46 reinterpret_cast<void*>(res->uniform_data_->writable_data());
47 return Dart_NewExternalTypedData(Dart_TypedData_kFloat32, raw_uniform_data,
48 float_count);
49}
50
51bool ReusableFragmentShader::ValidateSamplers() {
52 for (auto i = 0u; i < samplers_.size(); i++) {
53 if (samplers_[i] == nullptr) {
54 return false;
55 }
56 // The samplers should have been checked as they were added, this
57 // is a double-sanity-check.
58 FML_DCHECK(samplers_[i]->isUIThreadSafe());
59 }
60 return true;
61}
62
63void ReusableFragmentShader::SetImageSampler(Dart_Handle index_handle,
64 Dart_Handle image_handle,
65 int filterQualityIndex) {
66 uint64_t index = tonic::DartConverter<uint64_t>::FromDart(index_handle);
69 if (index >= samplers_.size()) {
70 Dart_ThrowException(tonic::ToDart("Sampler index out of bounds"));
71 return;
72 }
73 if (!image || !image->image()) {
74 Dart_ThrowException(tonic::ToDart("Image has been disposed"));
75 return;
76 }
77 if (!image->image()->isUIThreadSafe()) {
78 Dart_ThrowException(tonic::ToDart("Image is not thread-safe"));
79 return;
80 }
81
82 // TODO(115794): Once the DlImageSampling enum is replaced, expose the
83 // sampling options as a new default parameter for users.
84 samplers_[index] = DlColorSource::MakeImage(
85 image->image(), DlTileMode::kClamp, DlTileMode::kClamp,
86 ImageFilter::SamplingFromIndex(filterQualityIndex), nullptr);
87 // This should be true since we already checked the image above, but
88 // we check again for sanity.
89 FML_DCHECK(samplers_[index]->isUIThreadSafe());
90
91 auto* uniform_floats =
92 reinterpret_cast<float*>(uniform_data_->writable_data());
93 uniform_floats[float_count_ + 2 * index] = image->width();
94 uniform_floats[float_count_ + 2 * index + 1] = image->height();
95}
96
97std::shared_ptr<DlImageFilter> ReusableFragmentShader::as_image_filter() const {
98 FML_CHECK(program_);
99
100 // The lifetime of this object is longer than a frame, and the uniforms can be
101 // continually changed on the UI thread. So we take a copy of the uniforms
102 // before handing it to the DisplayList for consumption on the render thread.
103 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
104 uniform_data->resize(uniform_data_->size());
105 memcpy(uniform_data->data(), uniform_data_->bytes(), uniform_data->size());
106
107 return program_->MakeDlImageFilter(std::move(uniform_data), samplers_);
108}
109
110std::shared_ptr<DlColorSource> ReusableFragmentShader::shader(
111 DlImageSampling sampling) {
112 FML_CHECK(program_);
113
114 // The lifetime of this object is longer than a frame, and the uniforms can be
115 // continually changed on the UI thread. So we take a copy of the uniforms
116 // before handing it to the DisplayList for consumption on the render thread.
117 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
118 uniform_data->resize(uniform_data_->size());
119 memcpy(uniform_data->data(), uniform_data_->bytes(), uniform_data->size());
120
121 auto source = program_->MakeDlColorSource(std::move(uniform_data), samplers_);
122 // The samplers should have been checked as they were added, this
123 // is a double-sanity-check.
124 FML_DCHECK(source->isUIThreadSafe());
125 return source;
126}
127
128// Image filters require at least one uniform sampler input to bind
129// the input texture.
130bool ReusableFragmentShader::ValidateImageFilter() {
131 if (samplers_.size() < 1) {
132 return false;
133 }
134 // The first sampler does not need to be set.
135 for (auto i = 1u; i < samplers_.size(); i++) {
136 if (samplers_[i] == nullptr) {
137 return false;
138 }
139 // The samplers should have been checked as they were added, this
140 // is a double-sanity-check.
141 FML_DCHECK(samplers_[i]->isUIThreadSafe());
142 }
143 return true;
144}
145
146void ReusableFragmentShader::Dispose() {
147 uniform_data_.reset();
148 program_ = nullptr;
149 samplers_.clear();
150 ClearDartWrapper();
151}
152
153ReusableFragmentShader::~ReusableFragmentShader() = default;
154
155} // namespace flutter
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
FlutterVulkanImage * image
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_DCHECK(condition)
Definition logging.h:122
RefPtr< T > Ref(T *ptr)
Definition ref_ptr.h:242
Definition ref_ptr.h:261
Dart_Handle ToDart(const T &object)
FlutterVulkanImageHandle image
Definition embedder.h:931