react-native-webgpu 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cpp/rnwgpu/api/GPUQueue.cpp +39 -13
- package/package.json +1 -1
|
@@ -128,6 +128,30 @@ void GPUQueue::copyExternalImageToTexture(
|
|
|
128
128
|
throw std::runtime_error("Invalid input for GPUQueue::writeTexture()");
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
const auto origin = source->origin.value_or(nullptr);
|
|
132
|
+
// GPUOrigin2D coordinates are [EnforceRange] unsigned long: negative,
|
|
133
|
+
// NaN, or out-of-range doubles must be rejected here because casting
|
|
134
|
+
// them to an unsigned integer is undefined behavior.
|
|
135
|
+
constexpr double kMaxOrigin =
|
|
136
|
+
static_cast<double>(std::numeric_limits<uint32_t>::max());
|
|
137
|
+
if (origin && (!(origin->x >= 0) || !(origin->y >= 0) ||
|
|
138
|
+
origin->x > kMaxOrigin || origin->y > kMaxOrigin)) {
|
|
139
|
+
throw std::runtime_error(
|
|
140
|
+
"The source origin must be a non-negative integer coordinate.");
|
|
141
|
+
}
|
|
142
|
+
const size_t sourceOriginX =
|
|
143
|
+
origin ? static_cast<size_t>(origin->x) : 0;
|
|
144
|
+
const size_t sourceOriginY =
|
|
145
|
+
origin ? static_cast<size_t>(origin->y) : 0;
|
|
146
|
+
if (sourceOriginX > source->source->getWidth() ||
|
|
147
|
+
sz.width > source->source->getWidth() - sourceOriginX ||
|
|
148
|
+
sourceOriginY > source->source->getHeight() ||
|
|
149
|
+
sz.height > source->source->getHeight() - sourceOriginY ||
|
|
150
|
+
sz.depthOrArrayLayers > 1) {
|
|
151
|
+
throw std::runtime_error(
|
|
152
|
+
"The source copy region is outside the ImageBitmap.");
|
|
153
|
+
}
|
|
154
|
+
|
|
131
155
|
const bool flipY = source->flipY.value_or(false);
|
|
132
156
|
// premultipliedAlpha defaults to false per the WebGPU spec: an untagged
|
|
133
157
|
// destination expects straight alpha. Convert only when the ImageBitmap's
|
|
@@ -138,28 +162,30 @@ void GPUQueue::copyExternalImageToTexture(
|
|
|
138
162
|
const bool needsAlphaConversion =
|
|
139
163
|
bytesPerPixel == 4 && sourcePremultiplied != destinationPremultiplied;
|
|
140
164
|
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
uint32_t
|
|
165
|
+
if (sourceOriginX != 0 || sourceOriginY != 0 || flipY ||
|
|
166
|
+
needsAlphaConversion) {
|
|
167
|
+
uint32_t sourceRowSize = bytesPerPixel * source->source->getWidth();
|
|
168
|
+
uint32_t rowSize = bytesPerPixel * sz.width;
|
|
169
|
+
uint32_t totalSize = rowSize * sz.height;
|
|
144
170
|
|
|
145
|
-
// Stage
|
|
146
|
-
// ImageBitmap's backing store.
|
|
171
|
+
// Stage only the selected subregion so transformations never touch the
|
|
172
|
+
// ImageBitmap's backing store or pixels outside the requested copy.
|
|
147
173
|
std::vector<uint8_t> staged(totalSize);
|
|
148
174
|
const uint8_t *src =
|
|
149
175
|
static_cast<const uint8_t *>(source->source->getData());
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
} else {
|
|
157
|
-
std::memcpy(staged.data(), src, totalSize);
|
|
176
|
+
for (uint32_t row = 0; row < sz.height; ++row) {
|
|
177
|
+
const uint32_t sourceRow =
|
|
178
|
+
sourceOriginY + (flipY ? sz.height - 1 - row : row);
|
|
179
|
+
const uint32_t sourceOffset =
|
|
180
|
+
sourceRow * sourceRowSize + sourceOriginX * bytesPerPixel;
|
|
181
|
+
std::memcpy(staged.data() + row * rowSize, src + sourceOffset, rowSize);
|
|
158
182
|
}
|
|
159
183
|
if (needsAlphaConversion) {
|
|
160
184
|
convertAlpha(staged.data(), totalSize, sourcePremultiplied,
|
|
161
185
|
destinationPremultiplied);
|
|
162
186
|
}
|
|
187
|
+
layout.bytesPerRow = rowSize;
|
|
188
|
+
layout.rowsPerImage = sz.height;
|
|
163
189
|
_instance.WriteTexture(&dst, staged.data(), totalSize, &layout, &sz);
|
|
164
190
|
} else {
|
|
165
191
|
_instance.WriteTexture(&dst, source->source->getData(),
|