32UploadInstance::UploadInstance() =
default;
33UploadInstance::UploadInstance(UploadInstance&&) =
default;
37UploadInstance::UploadInstance(
const Buffer*
buffer,
40 std::unique_ptr<ConditionalUploadContext> condContext)
42 , fBytesPerPixel(bytesPerPixel)
43 , fTextureProxy(textureProxy)
44 , fConditionalContext(
std::move(condContext)) {}
55 TArray<std::pair<size_t, size_t>>* levelOffsetsAndRowBytes) {
56 SkASSERT(levelOffsetsAndRowBytes && !levelOffsetsAndRowBytes->size());
62 size_t minTransferBufferAlignment =
64 size_t alignedBytesPerRow =
67 levelOffsetsAndRowBytes->push_back({0, alignedBytesPerRow});
68 size_t combinedBufferSize =
SkAlignTo(alignedBytesPerRow * baseDimensions.
height(),
69 minTransferBufferAlignment);
70 SkISize levelDimensions = baseDimensions;
72 for (
int currentMipLevel = 1; currentMipLevel < mipLevelCount; ++currentMipLevel) {
73 levelDimensions = {std::max(1, levelDimensions.
width() / 2),
74 std::max(1, levelDimensions.
height() / 2)};
77 compressedBlockDimensions.
width() * bytesPerBlock);
78 size_t alignedSize =
SkAlignTo(alignedBytesPerRow * compressedBlockDimensions.
height(),
79 minTransferBufferAlignment);
80 SkASSERT(combinedBufferSize % minTransferBufferAlignment == 0);
82 levelOffsetsAndRowBytes->push_back({combinedBufferSize, alignedBytesPerRow});
83 combinedBufferSize += alignedSize;
86 SkASSERT(levelOffsetsAndRowBytes->size() == mipLevelCount);
87 SkASSERT(combinedBufferSize % minTransferBufferAlignment == 0);
88 return {combinedBufferSize, minTransferBufferAlignment};
97 std::unique_ptr<ConditionalUploadContext> condContext) {
101 textureProxy->textureInfo()));
103 unsigned int mipLevelCount = levels.
size();
110 unsigned int numExpectedLevels = 1;
111 if (textureProxy->textureInfo().mipmapped() == Mipmapped::kYes) {
113 textureProxy->dimensions().height()) + 1;
115 SkASSERT(mipLevelCount == 1 || mipLevelCount == numExpectedLevels);
122 if (mipLevelCount == 1 && !levels[0].fPixels) {
126 for (
unsigned int i = 0; i < mipLevelCount; ++i) {
128 if (!levels[i].fPixels) {
135 std::tie(supportedColorType, isRGB888Format) =
137 textureProxy->textureInfo(),
152 &levelOffsetsAndRowBytes);
158 SKGPU_LOG_W(
"Failed to get write-mapped buffer for texture upload of size %zu",
163 UploadInstance upload{bufferInfo.fBuffer, bpp, std::move(textureProxy), std::move(condContext)};
166 int32_t currentWidth = dstRect.
width();
167 int32_t currentHeight = dstRect.
height();
168 bool needsConversion = (srcColorInfo != dstColorInfo);
169 for (
unsigned int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
170 const size_t trimRowBytes = currentWidth * bpp;
171 const size_t srcRowBytes = levels[currentMipLevel].fRowBytes;
172 const auto [mipOffset, dstRowBytes] = levelOffsetsAndRowBytes[currentMipLevel];
175 const char* src = (
const char*)levels[currentMipLevel].fPixels;
177 if (isRGB888Format) {
180 SkISize dims = {currentWidth, currentHeight};
184 const void* rgbConvertSrc = src;
185 size_t rgbSrcRowBytes = srcRowBytes;
187 if (needsConversion) {
188 temp.
alloc(dstImageInfo);
195 rgbConvertSrc = temp.
addr();
198 writer.writeRGBFromRGBx(mipOffset,
204 }
else if (needsConversion) {
205 SkISize dims = {currentWidth, currentHeight};
209 writer.convertAndWrite(
210 mipOffset, srcImageInfo, src, srcRowBytes, dstImageInfo, dstRowBytes);
212 writer.write(mipOffset, src, srcRowBytes, dstRowBytes, trimRowBytes, currentHeight);
217 upload.fCopyData.push_back({
218 bufferInfo.fOffset + mipOffset,
224 currentWidth = std::max(1, currentWidth / 2);
225 currentHeight = std::max(1, currentHeight / 2);
229 mipLevelCount > 1 ?
"MipMap " :
"",
243 const TextureInfo& texInfo = textureProxy->textureInfo();
254 const SkISize dimensions = textureProxy->dimensions();
262 unsigned int mipLevelCount = srcMipOffsets.
size();
271 &levelOffsetsAndRowBytes);
277 std::vector<BufferTextureCopyData> copyData(mipLevelCount);
279 if (!bufferInfo.fBuffer) {
280 SKGPU_LOG_W(
"Failed to get write-mapped buffer for texture upload of size %zu",
288 int32_t currentWidth = dimensions.
width();
289 int32_t currentHeight = dimensions.
height();
290 for (
unsigned int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
292 {currentWidth, currentHeight});
293 int32_t blockHeight = blockDimensions.
height();
296 const size_t srcRowBytes = trimRowBytes;
297 const auto [dstMipOffset, dstRowBytes] = levelOffsetsAndRowBytes[currentMipLevel];
300 const void* src = SkTAddOffset<const void>(data, srcMipOffsets[currentMipLevel]);
302 writer.write(dstMipOffset, src, srcRowBytes, dstRowBytes, trimRowBytes, blockHeight);
304 int32_t copyWidth = currentWidth;
305 int32_t copyHeight = currentHeight;
312 upload.fCopyData.push_back({
313 bufferInfo.fOffset + dstMipOffset,
319 currentWidth = std::max(1, currentWidth / 2);
320 currentHeight = std::max(1, currentHeight / 2);
324 mipLevelCount > 1 ?
"MipMap " :
"",
332 if (!fTextureProxy) {
333 SKGPU_LOG_E(
"No texture proxy specified for UploadTask");
336 if (!TextureProxy::InstantiateIfNotLazy(resourceProvider, fTextureProxy.get())) {
337 SKGPU_LOG_E(
"Could not instantiate texture proxy for UploadTask!");
347 SkASSERT(fTextureProxy && fTextureProxy->isInstantiated());
349 if (fConditionalContext && !fConditionalContext->needsUpload(context)) {
352 return Status::kSuccess;
355 if (fTextureProxy->texture() != replayData.
fTarget) {
359 fTextureProxy->refTexture(),
362 return Status::kFail;
371 SkIRect croppedDstRect = dstRect;
375 return Status::kSuccess;
381 (croppedDstRect.
x() - dstRect.
x()) * fBytesPerPixel;
382 transformedCopyData.
fRect = croppedDstRect;
385 fTextureProxy->refTexture(),
386 &transformedCopyData, 1)) {
387 return Status::kFail;
393 if (!fConditionalContext || fConditionalContext->uploadSubmitted()) {
394 return Status::kSuccess;
396 return Status::kDiscard;
408 std::unique_ptr<ConditionalUploadContext> condContext) {
410 srcColorInfo, dstColorInfo,
411 levels, dstRect, std::move(condContext));
416 fInstances.emplace_back(std::move(
instance));
424 if (!uploadList->
size()) {
438 : fInstances(
std::move(instances)) {}
440UploadTask::UploadTask(UploadInstance
instance) {
441 fInstances.emplace_back(std::move(
instance));
448 for (
int i = 0; i < fInstances.size(); ++i) {
452 return Status::kFail;
456 return Status::kSuccess;
462 int discardCount = 0;
463 for (
int i = 0; i < fInstances.size(); ++i) {
464 if (!fInstances[i].isValid()) {
468 Status status = fInstances[i].addCommand(context, commandBuffer, replayData);
469 if (status == Status::kFail) {
470 return Status::kFail;
471 }
else if (status == Status::kDiscard) {
477 if (discardCount == fInstances.size()) {
478 return Status::kDiscard;
480 return Status::kSuccess;
#define SKGPU_LOG_E(fmt,...)
#define SKGPU_LOG_W(fmt,...)
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
#define SkAssertResult(cond)
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
@ kUnknown_SkColorType
uninitialized
size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)
size_t SkCompressedBlockSize(SkTextureCompressionType type)
bool SkConvertPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRB, const SkImageInfo &srcInfo, const void *srcPixels, size_t srcRB)
SK_API int SkColorTypeBytesPerPixel(SkColorType ct)
#define ATRACE_ANDROID_FRAMEWORK(fmt,...)
void alloc(const SkImageInfo &)
SkColorType colorType() const
static int ComputeLevelCount(int baseWidth, int baseHeight)
void * writable_addr() const
const void * addr() const
constexpr size_t size() const
bool isTexturable(const TextureInfo &) const
virtual std::pair< SkColorType, bool > supportedWritePixelsColorType(SkColorType dstColorType, const TextureInfo &dstTextureInfo, SkColorType srcColorType) const =0
bool fullCompressedUploadSizeMustAlignToBlockDims() const
size_t getAlignedTextureDataRowBytes(size_t rowBytes) const
bool areColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo &) const
size_t requiredTransferBufferAlignment() const
bool copyBufferToTexture(const Buffer *, sk_sp< Texture >, const BufferTextureCopyData *, int count)
const Caps * caps() const
UploadBufferManager * uploadBufferManager()
Mipmapped mipmapped() const
SkTextureCompressionType compressionType() const
std::tuple< TextureUploadWriter, BindBufferInfo > getTextureUploadWriter(size_t requiredBytes, size_t requiredAlignment)
static UploadInstance Invalid()
UploadInstance & operator=(UploadInstance &&)
Status prepareResources(ResourceProvider *, const RuntimeEffectDictionary *) override
Status addCommands(Context *, CommandBuffer *, ReplayTargetData) override
static const uint8_t buffer[]
std::pair< size_t, size_t > compute_combined_buffer_size(const Caps *caps, int mipLevelCount, size_t bytesPerBlock, const SkISize &baseDimensions, SkTextureCompressionType compressionType, TArray< std::pair< size_t, size_t > > *levelOffsetsAndRowBytes)
SkISize CompressedDimensionsInBlocks(SkTextureCompressionType type, SkISize baseDimensions)
size_t CompressedRowBytes(SkTextureCompressionType type, int width)
SkISize CompressedDimensions(SkTextureCompressionType type, SkISize baseDimensions)
constexpr int32_t x() const
constexpr int32_t y() const
bool intersect(const SkIRect &r)
constexpr int32_t top() const
constexpr SkISize size() const
constexpr int32_t height() const
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
void offset(int32_t dx, int32_t dy)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
constexpr int32_t left() const
constexpr int32_t width() const
constexpr int32_t height() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)