45#if !__has_feature(objc_arc)
46#error This file must be compiled with Arc. Use -fobjc-arc flag
51#if defined(GR_TEST_UTILS)
53#define GR_METAL_CAPTURE_COMMANDBUFFER 0
62 if (@available(macOS 10.14, iOS 10.0, tvOS 10.0, *)) {
65 SkDebugf(
"*** Error ***: Skia's Metal backend no longer supports this OS version.\n");
66#ifdef SK_BUILD_FOR_IOS
67 SkDebugf(
"Minimum supported version is iOS 10.0.\n");
69 SkDebugf(
"Minimum supported version is MacOS 10.14.\n");
74 id<MTLDevice> GR_NORETAIN
device = (__bridge id<MTLDevice>)(context.
fDevice.get());
75 id<MTLCommandQueue> GR_NORETAIN
queue = (__bridge id<MTLCommandQueue>)(context.
fQueue.get());
77 return std::unique_ptr<GrGpu>(
new GrMtlGpu(direct,
90 id<MTLDevice>
device, id<MTLCommandQueue> queue)
95 , fResourceProvider(this)
96 , fStagingBufferManager(this)
98 , fDisconnected(false) {
100 this->initCaps(fMtlCaps);
101#if GR_METAL_CAPTURE_COMMANDBUFFER
102 this->testingOnly_startCapture();
108 if (!fDisconnected) {
109 this->destroyResources();
116 if (!fDisconnected) {
117 this->destroyResources();
118 fDisconnected =
true;
130void GrMtlGpu::destroyResources() {
133 fCurrentCmdBuffer = nil;
137 while (!fOutstandingCommandBuffers.
empty()) {
138 OutstandingCommandBuffer*
buffer =
139 (OutstandingCommandBuffer*)fOutstandingCommandBuffers.
front();
142 buffer->~OutstandingCommandBuffer();
145 fStagingBufferManager.
reset();
168 bool withResolve =
false;
173 if (useMSAASurface && this->
mtlCaps().renderTargetSupportsDiscardableMSAA(mtlRT)) {
183 return new GrMtlOpsRenderPass(
this, renderTarget, std::move(framebuffer), origin, colorInfo,
188 if (!fCurrentCmdBuffer) {
189#if GR_METAL_CAPTURE_COMMANDBUFFER
190 this->testingOnly_startCapture();
197 return fCurrentCmdBuffer.
get();
211bool GrMtlGpu::submitCommandBuffer(SyncQueue sync) {
212 if (!fCurrentCmdBuffer || !fCurrentCmdBuffer->
hasWork()) {
215 this->checkForFinishedCommandBuffers();
219 if (fCurrentCmdBuffer) {
228 new (fOutstandingCommandBuffers.
push_back()) OutstandingCommandBuffer(fCurrentCmdBuffer);
234 fCurrentCmdBuffer.
reset();
238 this->checkForFinishedCommandBuffers();
240#if GR_METAL_CAPTURE_COMMANDBUFFER
241 this->testingOnly_stopCapture();
246void GrMtlGpu::checkForFinishedCommandBuffers() {
252 OutstandingCommandBuffer* front = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.
front();
253 while (front && (*front)->isCompleted()) {
257 front->~OutstandingCommandBuffer();
258 front = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.
front();
267 (*back)->waitUntilCompleted();
285 OutstandingCommandBuffer* back = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.
back();
287 (*back)->addFinishedCallback(finishedCallback);
312 if (widthInPixels > 32767) {
335 if (
rect.isEmpty()) {
342 id<MTLTexture> GR_NORETAIN mtlTexture = tex->
mtlTexture();
345 SkASSERT(1 == mipLevelCount || mipLevelCount == (
int)mtlTexture.mipmapLevelCount);
347 if (mipLevelCount == 1 && !texels[0].fPixels) {
351 for (
int i = 0; i < mipLevelCount; ++i) {
353 if (!texels[i].fPixels) {
363 &individualMipOffsets,
369 size_t alignment = std::max(bpp, this->
mtlCaps().getMinBufferAlignment());
371 combinedBufferSize, alignment);
378 int currentWidth =
rect.width();
379 int currentHeight =
rect.height();
381 MTLOrigin origin = MTLOriginMake(
rect.left(),
rect.top(), 0);
384 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
385 if (!blitCmdEncoder) {
388#ifdef SK_ENABLE_MTL_DEBUG_INFO
389 [blitCmdEncoder pushDebugGroup:
@"uploadToTexture"];
391 for (
int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
392 if (texels[currentMipLevel].fPixels) {
393 SkASSERT(1 == mipLevelCount || currentHeight == layerHeight);
394 const size_t trimRowBytes = currentWidth * bpp;
395 const size_t rowBytes = texels[currentMipLevel].
fRowBytes;
398 char*
dst = bufferData + individualMipOffsets[currentMipLevel];
399 const char*
src = (
const char*)texels[currentMipLevel].fPixels;
400 SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight);
402 [blitCmdEncoder copyFromBuffer: mtlBuffer->
mtlBuffer()
403 sourceOffset: slice.
fOffset + individualMipOffsets[currentMipLevel]
404 sourceBytesPerRow: trimRowBytes
405 sourceBytesPerImage: trimRowBytes*currentHeight
406 sourceSize: MTLSizeMake(currentWidth, currentHeight, 1)
407 toTexture: mtlTexture
409 destinationLevel: currentMipLevel
410 destinationOrigin: origin];
412 currentWidth =
std::
max(1, currentWidth/2);
413 currentHeight =
std::
max(1, currentHeight/2);
416#ifdef SK_BUILD_FOR_MAC
418 [mtlBuffer->
mtlBuffer() didModifyRange: NSMakeRange(slice.
fOffset, combinedBufferSize)];
421#ifdef SK_ENABLE_MTL_DEBUG_INFO
422 [blitCmdEncoder popDebugGroup];
425 if (mipLevelCount < (
int) tex->
mtlTexture().mipmapLevelCount) {
432bool GrMtlGpu::clearTexture(
GrMtlTexture* tex,
size_t bpp, uint32_t levelMask) {
439 id<MTLTexture> GR_NORETAIN mtlTexture = tex->
mtlTexture();
442 int mipLevelCount = (
int)mtlTexture.mipmapLevelCount;
445 size_t combinedBufferSize = 0;
446 int currentWidth = tex->
width();
447 int currentHeight = tex->
height();
454 const size_t alignmentMask = 0x3 | (bpp - 1);
455 for (
int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
456 if (levelMask & (1 << currentMipLevel)) {
457 const size_t trimmedSize = currentWidth * bpp * currentHeight;
458 const size_t alignmentDiff = combinedBufferSize & alignmentMask;
459 if (alignmentDiff != 0) {
460 combinedBufferSize += alignmentMask - alignmentDiff + 1;
462 individualMipOffsets.push_back(combinedBufferSize);
463 combinedBufferSize += trimmedSize;
465 currentWidth = std::max(1, currentWidth/2);
466 currentHeight = std::max(1, currentHeight/2);
468 SkASSERT(combinedBufferSize > 0 && !individualMipOffsets.empty());
470 size_t alignment = std::max(bpp, this->
mtlCaps().getMinBufferAlignment());
472 combinedBufferSize, alignment);
477 id<MTLBuffer> transferBuffer = mtlBuffer->
mtlBuffer();
480 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
481 if (!blitCmdEncoder) {
484#ifdef SK_ENABLE_MTL_DEBUG_INFO
485 [blitCmdEncoder pushDebugGroup:
@"clearTexture"];
489 clearRange.location = 0;
490 clearRange.length = combinedBufferSize;
491 [blitCmdEncoder fillBuffer: transferBuffer
496 currentWidth = tex->
width();
497 currentHeight = tex->
height();
498 MTLOrigin origin = MTLOriginMake(0, 0, 0);
499 for (
int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
500 if (levelMask & (1 << currentMipLevel)) {
501 const size_t rowBytes = currentWidth * bpp;
503 [blitCmdEncoder copyFromBuffer: transferBuffer
504 sourceOffset: individualMipOffsets[currentMipLevel]
505 sourceBytesPerRow: rowBytes
506 sourceBytesPerImage: rowBytes * currentHeight
507 sourceSize: MTLSizeMake(currentWidth, currentHeight, 1)
508 toTexture: mtlTexture
510 destinationLevel: currentMipLevel
511 destinationOrigin: origin];
513 currentWidth =
std::
max(1, currentWidth/2);
514 currentHeight =
std::
max(1, currentHeight/2);
517#ifdef SK_ENABLE_MTL_DEBUG_INFO
518 [blitCmdEncoder popDebugGroup];
521 if (mipLevelCount < (
int) tex->
mtlTexture().mipmapLevelCount) {
529 SkISize dimensions,
int numStencilSamples) {
533 return GrMtlAttachment::GrMtlAttachment::MakeStencil(
this, dimensions, numStencilSamples, sFmt);
542 SkASSERT(isProtected == GrProtected::kNo);
547 SkASSERT(pixelFormat != MTLPixelFormatInvalid);
558 int renderTargetSampleCnt,
562 uint32_t levelClearMask,
563 std::string_view label) {
565 if (isProtected == GrProtected::kYes) {
571 SkASSERT(mtlPixelFormat != MTLPixelFormatInvalid);
577 if (renderable == GrRenderable::kYes) {
579 this, budgeted, dimensions, renderTargetSampleCnt, mtlPixelFormat, mipLevelCount,
580 mipmapStatus, label);
583 mipLevelCount, mipmapStatus, label);
590 if (levelClearMask) {
591 this->clearTexture(tex.
get(),
596 return std::move(tex);
607 if (isProtected == GrProtected::kYes) {
621 int numMipLevels = 1;
622 if (mipmapped == skgpu::Mipmapped::kYes) {
626 GrMipmapStatus mipmapStatus = (mipmapped == skgpu::Mipmapped::kYes)
631 numMipLevels, mipmapStatus,
632 "MtlGpu_CreateCompressedTexture");
638 id<MTLTexture> GR_NORETAIN mtlTexture = tex->
mtlTexture();
648 &individualMipOffsets,
649 mipmapped == skgpu::Mipmapped::kYes);
651 SkASSERT(dataSize == combinedBufferSize);
657 dataSize, alignment);
664 MTLOrigin origin = MTLOriginMake(0, 0, 0);
667 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
668 if (!blitCmdEncoder) {
671#ifdef SK_ENABLE_MTL_DEBUG_INFO
672 [blitCmdEncoder pushDebugGroup:
@"onCreateCompressedTexture"];
676 memcpy(bufferData, data, dataSize);
678 SkISize levelDimensions = dimensions;
679 for (
int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
681 levelDimensions.
width());
685 [blitCmdEncoder copyFromBuffer: mtlBuffer->
mtlBuffer()
686 sourceOffset: slice.
fOffset + individualMipOffsets[currentMipLevel]
687 sourceBytesPerRow: levelRowBytes
688 sourceBytesPerImage: levelSize
689 sourceSize: MTLSizeMake(levelDimensions.
width(),
690 levelDimensions.
height(), 1)
691 toTexture: mtlTexture
693 destinationLevel: currentMipLevel
694 destinationOrigin: origin];
696 levelDimensions = {std::max(1, levelDimensions.
width() /2),
697 std::max(1, levelDimensions.
height()/2)};
699#ifdef SK_BUILD_FOR_MAC
701 [mtlBuffer->
mtlBuffer() didModifyRange: NSMakeRange(slice.
fOffset, dataSize)];
704#ifdef SK_ENABLE_MTL_DEBUG_INFO
705 [blitCmdEncoder popDebugGroup];
708 return std::move(tex);
714 GrMtlTextureInfo textureInfo;
722 GrMtlTextureInfo textureInfo;
738 if (mtlTexture.sampleCount != 1) {
754 if (mtlTexture.sampleCount != 1) {
771 if (mtlTexture.sampleCount != 1) {
777 MTLPixelFormat
format = mtlTexture.pixelFormat;
782 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
783 SkASSERT(MTLTextureUsageRenderTarget & mtlTexture.usage);
790 this, backendTex.
dimensions(), sampleCnt, mtlTexture, cacheable);
803 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
804 SkASSERT(MTLTextureUsageRenderTarget & mtlTexture.usage);
813 id<MTLTexture> GR_NORETAIN mtlTexture = grMtlTexture->
mtlTexture();
818 MTLPixelFormatRGBA8Unorm != mtlTexture.pixelFormat) {
823 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
824 if (!blitCmdEncoder) {
827 [blitCmdEncoder generateMipmapsForTexture: mtlTexture];
860 size_t bytesPerPixel,
868 for (
int level = 0; level < numMipLevels; ++level) {
869 const size_t trimRB = srcData[level].
width() * bytesPerPixel;
870 SkASSERT(individualMipOffsets[level] + trimRB * srcData[level].
height() <= bufferSize);
872 srcData[level].addr(), srcData[level].rowBytes(),
873 trimRB, srcData[level].
height());
877bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat mtlFormat,
883 GrMtlTextureInfo*
info) {
889 if (renderable == GrRenderable::kYes && !fMtlCaps->
isFormatRenderable(mtlFormat, 1)) {
897 auto desc = [[MTLTextureDescriptor alloc]
init];
898 desc.pixelFormat = mtlFormat;
901 if (mipmapped == skgpu::Mipmapped::kYes) {
904 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
905 desc.storageMode = MTLStorageModePrivate;
907 usage |= renderable == GrRenderable::kYes ? MTLTextureUsageRenderTarget : 0;
910 if (sampleCnt != 1) {
911 desc.sampleCount = sampleCnt;
912 desc.textureType = MTLTextureType2DMultisample;
914 id<MTLTexture> testTexture = [fDevice newTextureWithDescriptor:
desc];
915#ifdef SK_ENABLE_MTL_DEBUG_INFO
916 testTexture.label =
@"testTexture";
927 std::string_view label) {
930 GrMtlTextureInfo
info;
931 if (!this->createMtlTextureForBackendSurface(mtlFormat, dimensions, 1,
GrTexturable::kYes,
932 renderable, mipmapped, &
info)) {
941 std::array<float, 4>
color) {
942 GrMtlTextureInfo
info;
947 const MTLPixelFormat mtlFormat = mtlTexture.pixelFormat;
951 size_t combinedBufferSize;
954 combinedBufferSize = bytesPerPixel*backendTexture.
width()*backendTexture.
height();
956 size_t alignment = std::max(bytesPerPixel, this->
mtlCaps().getMinBufferAlignment());
958 combinedBufferSize, alignment);
976 MTLOrigin origin = MTLOriginMake(0, 0, 0);
980 if (!blitCmdEncoder) {
983#ifdef SK_ENABLE_MTL_DEBUG_INFO
984 [blitCmdEncoder pushDebugGroup:
@"onClearBackendTexture"];
989 int numMipLevels = mtlTexture.mipmapLevelCount;
990 for (
int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
991 size_t levelRowBytes;
994 levelRowBytes = levelDimensions.
width() * bytesPerPixel;
995 levelSize = levelRowBytes * levelDimensions.
height();
998 [blitCmdEncoder copyFromBuffer: mtlBuffer->
mtlBuffer()
1000 sourceBytesPerRow: levelRowBytes
1001 sourceBytesPerImage: levelSize
1002 sourceSize: MTLSizeMake(levelDimensions.
width(),
1003 levelDimensions.
height(),
1005 toTexture: mtlTexture
1007 destinationLevel: currentMipLevel
1008 destinationOrigin: origin];
1010 levelDimensions = {std::max(1, levelDimensions.
width() / 2),
1011 std::max(1, levelDimensions.
height() / 2)};
1013#ifdef SK_BUILD_FOR_MAC
1014 if (this->
mtlCaps().isMac()) {
1015 [mtlBuffer->
mtlBuffer() didModifyRange: NSMakeRange(slice.
fOffset, combinedBufferSize)];
1018 [blitCmdEncoder popDebugGroup];
1020 if (finishedCallback) {
1021 this->addFinishedCallback(std::move(finishedCallback));
1033 GrMtlTextureInfo
info;
1034 if (!this->createMtlTextureForBackendSurface(mtlFormat, dimensions, 1,
GrTexturable::kYes,
1035 GrRenderable::kNo, mipmapped, &
info)) {
1046 GrMtlTextureInfo
info;
1051 int numMipLevels = mtlTexture.mipmapLevelCount;
1052 skgpu::Mipmapped mipmapped = numMipLevels > 1 ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
1060 size_t combinedBufferSize;
1063 &individualMipOffsets,
1064 mipmapped == skgpu::Mipmapped::kYes);
1068 this->
mtlCaps().getMinBufferAlignment());
1076 memcpy(
buffer, data, size);
1079 MTLOrigin origin = MTLOriginMake(0, 0, 0);
1083 if (!blitCmdEncoder) {
1086#ifdef SK_ENABLE_MTL_DEBUG_INFO
1087 [blitCmdEncoder pushDebugGroup:
@"onUpdateCompressedBackendTexture"];
1092 for (
int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
1093 size_t levelRowBytes;
1100 [blitCmdEncoder copyFromBuffer: mtlBuffer->
mtlBuffer()
1101 sourceOffset: slice.
fOffset + individualMipOffsets[currentMipLevel]
1102 sourceBytesPerRow: levelRowBytes
1103 sourceBytesPerImage: levelSize
1104 sourceSize: MTLSizeMake(levelDimensions.
width(),
1105 levelDimensions.
height(),
1107 toTexture: mtlTexture
1109 destinationLevel: currentMipLevel
1110 destinationOrigin: origin];
1112 levelDimensions = {std::max(1, levelDimensions.
width() / 2),
1113 std::max(1, levelDimensions.
height() / 2)};
1115#ifdef SK_BUILD_FOR_MAC
1116 if (this->
mtlCaps().isMac()) {
1117 [mtlBuffer->
mtlBuffer() didModifyRange:NSMakeRange(slice.
fOffset, combinedBufferSize)];
1120 [blitCmdEncoder popDebugGroup];
1122 if (finishedCallback) {
1123 this->addFinishedCallback(std::move(finishedCallback));
1139 desc, programInfo, &stat);
1140 if (!pipelineState) {
1151#if defined(GR_TEST_UTILS)
1152bool GrMtlGpu::isTestingOnlyBackendTexture(
const GrBackendTexture& tex)
const {
1155 GrMtlTextureInfo
info;
1163 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
1164 return mtlTexture.usage & MTLTextureUsageShaderRead;
1174 if (dimensions.
width() > this->caps()->maxRenderTargetSize() ||
1175 dimensions.
height() > this->caps()->maxRenderTargetSize()) {
1178 if (isProtected == GrProtected::kYes) {
1184 if (sampleCnt == 0) {
1188 GrMtlTextureInfo
info;
1189 if (!this->createMtlTextureForBackendSurface(
format,
1194 skgpu::Mipmapped::kNo,
1205 GrMtlTextureInfo
info;
1224 dstAttachment =
static_cast<GrMtlTexture*
>(dst->asTexture())->attachment();
1236 srcRect, dstPoint, dst == src));
1238 id<MTLTexture> GR_NORETAIN dstTex = dstAttachment->
mtlTexture();
1239 id<MTLTexture> GR_NORETAIN srcTex = srcAttachment->
mtlTexture();
1242 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
1243 if (!blitCmdEncoder) {
1246#ifdef SK_ENABLE_MTL_DEBUG_INFO
1247 [blitCmdEncoder pushDebugGroup:
@"copySurfaceAsBlit"];
1249 [blitCmdEncoder copyFromTexture: srcTex
1252 sourceOrigin: MTLOriginMake(srcRect.
x(), srcRect.
y(), 0)
1253 sourceSize: MTLSizeMake(srcRect.
width(), srcRect.
height(), 1)
1257 destinationOrigin: MTLOriginMake(dstPoint.
fX, dstPoint.
fY, 0)];
1258#ifdef SK_ENABLE_MTL_DEBUG_INFO
1259 [blitCmdEncoder popDebugGroup];
1261 cmdBuffer->addGrSurface(sk_ref_sp<const GrSurface>(dst));
1262 cmdBuffer->addGrSurface(sk_ref_sp<const GrSurface>(src));
1268 SkASSERT(!src->isProtected() && !dst->isProtected());
1270 if (srcRect.
size() != dstRect.
size()) {
1287 }
else if (dst->asTexture()) {
1288 dstAttachment =
static_cast<GrMtlTexture*
>(dst->asTexture())->attachment();
1304 }
else if (src->asTexture()) {
1306 srcAttachment =
static_cast<GrMtlTexture*
>(src->asTexture())->attachment();
1312 MTLPixelFormat dstFormat = dstAttachment->
mtlFormat();
1313 MTLPixelFormat srcFormat = srcAttachment->
mtlFormat();
1320 srcFormat, srcSampleCnt,
1321 SkToBool(srcRT), src->dimensions(),
1323 dstAttachment == srcAttachment)) {
1332 if (this->
mtlCaps().canCopyAsBlit(dstFormat, dstSampleCnt, srcFormat, srcSampleCnt,
1333 srcRect, dstPoint, dstAttachment == srcAttachment)) {
1334 this->
copySurfaceAsBlit(dst, src, dstAttachment, srcAttachment, srcRect, dstPoint);
1347 bool prepForTexSampling) {
1354 if (!mipLevelCount) {
1358 for (
int i = 0; i < mipLevelCount; i++) {
1362 return this->uploadToTexture(mtlTexture, rect, srcColorType, texels, mipLevelCount);
1373 if (surfaceColorType != dstColorType) {
1378 size_t transBufferRowBytes = bpp*rect.width();
1379 size_t transBufferImageBytes = transBufferRowBytes*rect.height();
1383 transBufferImageBytes,
1388 if (!transferBuffer) {
1393 if (!this->readOrTransferPixels(
surface,
1398 transBufferImageBytes,
1399 transBufferRowBytes)) {
1404 const void* mappedMemory = grMtlBuffer->
mtlBuffer().contents;
1409 transBufferRowBytes,
1410 transBufferRowBytes,
1421 id<MTLBuffer> GR_NORETAIN mtlSrc =
static_cast<GrMtlBuffer*
>(src.get())->mtlBuffer();
1422 id<MTLBuffer> GR_NORETAIN mtlDst =
static_cast<GrMtlBuffer*
>(dst.get())->mtlBuffer();
1427 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
1428 if (!blitCmdEncoder) {
1432#ifdef SK_ENABLE_MTL_DEBUG_INFO
1433 [blitCmdEncoder pushDebugGroup:
@"onTransferFromBufferToBuffer"];
1435 [blitCmdEncoder copyFromBuffer: mtlSrc
1436 sourceOffset: srcOffset
1438 destinationOffset: dstOffset
1440#ifdef SK_ENABLE_MTL_DEBUG_INFO
1441 [blitCmdEncoder popDebugGroup];
1444 cmdBuffer->addGrBuffer(std::move(src));
1445 cmdBuffer->addGrBuffer(std::move(dst));
1459 if (textureColorType != bufferColorType) {
1464 id<MTLTexture> GR_NORETAIN mtlTexture = grMtlTexture->
mtlTexture();
1468 id<MTLBuffer> GR_NORETAIN mtlBuffer = grMtlBuffer->
mtlBuffer();
1479 MTLOrigin origin = MTLOriginMake(rect.left(), rect.top(), 0);
1482 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
1483 if (!blitCmdEncoder) {
1486#ifdef SK_ENABLE_MTL_DEBUG_INFO
1487 [blitCmdEncoder pushDebugGroup:
@"onTransferPixelsTo"];
1489 [blitCmdEncoder copyFromBuffer: mtlBuffer
1491 sourceBytesPerRow: rowBytes
1492 sourceBytesPerImage: rowBytes*rect.height()
1493 sourceSize: MTLSizeMake(rect.width(), rect.height(), 1)
1494 toTexture: mtlTexture
1497 destinationOrigin: origin];
1498#ifdef SK_ENABLE_MTL_DEBUG_INFO
1499 [blitCmdEncoder popDebugGroup];
1514 if (surfaceColorType != bufferColorType) {
1529 size_t transBufferRowBytes = bpp*rect.width();
1530 size_t transBufferImageBytes = transBufferRowBytes*rect.height();
1532 return this->readOrTransferPixels(
surface,
1537 transBufferImageBytes,
1538 transBufferRowBytes);
1544 id<MTLBuffer> transferBuffer,
1552 id<MTLTexture> mtlTexture;
1554 if (rt->numSamples() > 1) {
1555 SkASSERT(rt->requiresManualMSAAResolve());
1556 mtlTexture = rt->resolveMTLTexture();
1558 SkASSERT(!rt->requiresManualMSAAResolve());
1559 mtlTexture = rt->colorMTLTexture();
1562 mtlTexture =
texture->mtlTexture();
1569 id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
1570 if (!blitCmdEncoder) {
1573#ifdef SK_ENABLE_MTL_DEBUG_INFO
1574 [blitCmdEncoder pushDebugGroup:
@"readOrTransferPixels"];
1576 [blitCmdEncoder copyFromTexture: mtlTexture
1579 sourceOrigin: MTLOriginMake(
rect.left(),
rect.top(), 0)
1580 sourceSize: MTLSizeMake(rect.
width(), rect.
height(), 1)
1581 toBuffer: transferBuffer
1582 destinationOffset:
offset
1583 destinationBytesPerRow: rowBytes
1584 destinationBytesPerImage: imageBytes];
1585#ifdef SK_BUILD_FOR_MAC
1586 if (this->
mtlCaps().isMac()) {
1588 [blitCmdEncoder synchronizeResource: transferBuffer];
1591#ifdef SK_ENABLE_MTL_DEBUG_INFO
1592 [blitCmdEncoder popDebugGroup];
1612 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
1621 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
1644 auto renderPassDesc = [[MTLRenderPassDescriptor alloc] init];
1645 auto colorAttachment = renderPassDesc.colorAttachments[0];
1646 colorAttachment.texture = msaaAttachment->
mtlTexture();
1647 colorAttachment.resolveTexture = resolveAttachment->
mtlTexture();
1648 colorAttachment.loadAction = MTLLoadActionLoad;
1649 colorAttachment.storeAction = MTLStoreActionMultisampleResolve;
1654 cmdEncoder->
setLabel(
@"resolveTexture");
1662 MTLRenderPassStencilAttachmentDescriptor* stencil) {
1666 if (!src || src->framebufferOnly()) {
1672 MTLPixelFormat stencilFormat = stencil.texture.pixelFormat;
1678 auto renderPassDesc = [MTLRenderPassDescriptor
new];
1679 auto colorAttachment = renderPassDesc.colorAttachments[0];
1680 colorAttachment.texture = mtlDst->
mtlTexture();
1681 colorAttachment.loadAction = MTLLoadActionDontCare;
1682 colorAttachment.storeAction = MTLStoreActionMultisampleResolve;
1683 colorAttachment.resolveTexture = src->mtlTexture();
1685 renderPassDesc.stencilAttachment = stencil;
1690 auto renderCmdEncoder =
1692 if (!renderCmdEncoder) {
1701 renderCmdEncoder->setFragmentTexture(src->mtlTexture(), 0);
1712 int dw = dst->width();
1713 int dh = dst->height();
1714 float dx0 = 2.f * srcRect.
fLeft / dw - 1.f;
1715 float dx1 = 2.f * (srcRect.
fLeft +
w) / dw - 1.f;
1716 float dy0 = 2.f * srcRect.
fTop / dh - 1.f;
1717 float dy1 = 2.f * (srcRect.
fTop +
h) / dh - 1.f;
1723 } uniData = {{dx1 - dx0, dy1 - dy0, dx0, dy0}, {dw, dh}, {0, 0}};
1725 constexpr size_t uniformSize = 32;
1726 if (@available(macOS 10.11, iOS 8.3, tvOS 9.0, *)) {
1727 SkASSERT(uniformSize <= this->
caps()->maxPushConstantsSize());
1728 renderCmdEncoder->setVertexBytes(&uniData, uniformSize, 0);
1734 memcpy(destPtr, &uniData, uniformSize);
1736 renderCmdEncoder->setVertexBuffer(
buffer->mtlBuffer(), slice.
fOffset, 0);
1739 renderCmdEncoder->drawPrimitives(MTLPrimitiveTypeTriangleStrip, (NSUInteger)0, (NSUInteger)4);
1741 return renderCmdEncoder;
1744#if defined(GR_TEST_UTILS)
1745void GrMtlGpu::testingOnly_startCapture() {
1746 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1748 MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
1749 if (captureManager.isCapturing) {
1752 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
1753 MTLCaptureDescriptor* captureDescriptor = [[MTLCaptureDescriptor alloc]
init];
1754 captureDescriptor.captureObject = fQueue;
1757 if (![captureManager startCaptureWithDescriptor: captureDescriptor
error:&
error])
1759 NSLog(
@"Failed to start capture, error %@",
error);
1762 [captureManager startCaptureWithCommandQueue: fQueue];
1767void GrMtlGpu::testingOnly_stopCapture() {
1768 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1769 MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
1770 if (captureManager.isCapturing) {
1771 [captureManager stopCapture];
1777#ifdef SK_ENABLE_DUMP_GPU
1786#ifdef SK_BUILD_FOR_MAC
1787 if (@available(macOS 10.11, *)) {
1788 writer->
appendBool(
"isHeadless", fDevice.isHeadless);
1789 writer->
appendBool(
"isLowPower", fDevice.isLowPower);
1791 if (@available(macOS 10.13, *)) {
1792 writer->
appendBool(
"isRemovable", fDevice.isRemovable);
1795 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1796 writer->
appendU64(
"registryID", fDevice.registryID);
1798#if defined(SK_BUILD_FOR_MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
1799 if (@available(macOS 10.15, *)) {
1800 switch (fDevice.location) {
1801 case MTLDeviceLocationBuiltIn:
1804 case MTLDeviceLocationSlot:
1807 case MTLDeviceLocationExternal:
1810 case MTLDeviceLocationUnspecified:
1817 writer->
appendU64(
"locationNumber", fDevice.locationNumber);
1818 writer->
appendU64(
"maxTransferRate", fDevice.maxTransferRate);
1821#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
1822 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
1823 writer->
appendBool(
"hasUnifiedMemory", fDevice.hasUnifiedMemory);
1826#ifdef SK_BUILD_FOR_MAC
1827#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
1828 if (@available(macOS 10.15, *)) {
1829 writer->
appendU64(
"peerGroupID", fDevice.peerGroupID);
1830 writer->
appendU32(
"peerCount", fDevice.peerCount);
1831 writer->
appendU32(
"peerIndex", fDevice.peerIndex);
1834 if (@available(macOS 10.12, *)) {
1835 writer->
appendU64(
"recommendedMaxWorkingSetSize", fDevice.recommendedMaxWorkingSetSize);
1838 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1839 writer->
appendU64(
"currentAllocatedSize", fDevice.currentAllocatedSize);
1840 writer->
appendU64(
"maxThreadgroupMemoryLength", fDevice.maxThreadgroupMemoryLength);
1843 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
1845 writer->
appendU64(
"width", fDevice.maxThreadsPerThreadgroup.width);
1846 writer->
appendU64(
"height", fDevice.maxThreadsPerThreadgroup.height);
1847 writer->
appendU64(
"depth", fDevice.maxThreadsPerThreadgroup.depth);
1851 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1852 writer->
appendBool(
"areProgrammableSamplePositionsSupported",
1853 fDevice.areProgrammableSamplePositionsSupported);
1854 writer->
appendBool(
"areRasterOrderGroupsSupported",
1855 fDevice.areRasterOrderGroupsSupported);
1857#ifdef SK_BUILD_FOR_MAC
1858 if (@available(macOS 10.11, *)) {
1859 writer->
appendBool(
"isDepth24Stencil8PixelFormatSupported",
1860 fDevice.isDepth24Stencil8PixelFormatSupported);
1863#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
1864 if (@available(macOS 10.15, *)) {
1865 writer->
appendBool(
"areBarycentricCoordsSupported",
1866 fDevice.areBarycentricCoordsSupported);
1867 writer->
appendBool(
"supportsShaderBarycentricCoordinates",
1868 fDevice.supportsShaderBarycentricCoordinates);
1872 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
1873 writer->
appendU64(
"maxBufferLength", fDevice.maxBufferLength);
1875 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1876 switch (fDevice.readWriteTextureSupport) {
1877 case MTLReadWriteTextureTier1:
1880 case MTLReadWriteTextureTier2:
1883 case MTLReadWriteTextureTierNone:
1884 writer->
appendNString(
"readWriteTextureSupport",
"tierNone");
1887 writer->
appendNString(
"readWriteTextureSupport",
"unknown");
1890 switch (fDevice.argumentBuffersSupport) {
1891 case MTLArgumentBuffersTier1:
1894 case MTLArgumentBuffersTier2:
1902 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
1903 writer->
appendU64(
"maxArgumentBufferSamplerCount", fDevice.maxArgumentBufferSamplerCount);
1905#ifdef SK_BUILD_FOR_IOS
1906 if (@available(iOS 13.0, tvOS 13.0, *)) {
1907 writer->
appendU64(
"sparseTileSizeInBytes", fDevice.sparseTileSizeInBytes);
1913 writer->
appendBool(
"disconnected", fDisconnected);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
size_t GrBackendFormatBytesPerPixel(const GrBackendFormat &format)
SkTextureCompressionType GrBackendFormatToCompressionType(const GrBackendFormat &format)
size_t GrComputeTightCombinedBufferSize(size_t bytesPerPixel, SkISize baseDimensions, TArray< size_t > *individualMipOffsets, int mipLevelCount)
bool GrClearImage(const GrImageInfo &dstInfo, void *dst, size_t dstRB, std::array< float, 4 > color)
static GrColorType mtl_format_to_backend_tex_clear_colortype(MTLPixelFormat format)
static bool check_max_blit_width(int widthInPixels)
static const int kDefaultOutstandingAllocCnt
static id< MTLTexture > get_texture_from_backend(const GrBackendTexture &backendTex)
void copy_src_data(char *dst, size_t bytesPerPixel, const TArray< size_t > &individualMipOffsets, const GrPixmap srcData[], int numMipLevels, size_t bufferSize)
static MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat &format)
SK_ALWAYS_INLINE CF_RETURNS_RETAINED const void * GrRetainPtrFromId(id idObject)
GR_NORETAIN_BEGIN SK_ALWAYS_INLINE id< MTLTexture > GrGetMTLTexture(const void *mtlTexture)
static constexpr size_t GrColorTypeBytesPerPixel(GrColorType ct)
@ kDynamic_GrAccessPattern
void * GrGpuFinishedContext
void(* GrGpuFinishedProc)(GrGpuFinishedContext finishedContext)
#define SkAssertResult(cond)
size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)
size_t SkCompressedBlockSize(SkTextureCompressionType type)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static int SkPrevLog2(uint32_t value)
#define INHERITED(method,...)
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
sk_sp< T > sk_ref_sp(T *obj)
static constexpr bool SkToBool(const T &x)
Type::kYUV Type::kRGBA() int(0.7 *637)
GrBackendFormat getBackendFormat() const
GrBackendApi backend() const
SkISize dimensions() const
SkISize dimensions() const
GrBackendFormat getBackendFormat() const
GrBackendApi backend() const
virtual bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const =0
virtual int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const =0
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
void incStencilAttachmentCreates()
void incMSAAAttachmentCreates()
bool submitToGpu(GrSyncCpu sync)
const GrCaps * caps() const
GrDirectContext * getContext()
virtual void disconnect(DisconnectType)
size_t minRowBytes() const
MTLPixelFormat mtlFormat() const
bool framebufferOnly() const
unsigned int sampleCount() const
id< MTLTexture > mtlTexture() const
static sk_sp< GrMtlAttachment > MakeMSAA(GrMtlGpu *gpu, SkISize dimensions, int sampleCnt, MTLPixelFormat format)
static sk_sp< GrMtlBuffer > Make(GrMtlGpu *, size_t size, GrGpuBufferType intendedType, GrAccessPattern)
id< MTLBuffer > mtlBuffer() const
MTLPixelFormat preferredStencilFormat() const
MTLPixelFormat getFormatFromColorType(GrColorType colorType) const
bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const override
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const override
bool canCopyAsResolve(MTLPixelFormat dstFormat, int dstSampleCount, MTLPixelFormat srcFormat, int srcSampleCount, bool srcIsRenderTarget, const SkISize srcDimensions, const SkIRect &srcRect, const SkIPoint &dstPoint, bool areDstSrcSameObj) const
bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const override
bool renderTargetSupportsDiscardableMSAA(const GrMtlRenderTarget *) const
GrMtlRenderCommandEncoder * getRenderCommandEncoder(MTLRenderPassDescriptor *, const GrMtlPipelineState *, GrMtlOpsRenderPass *opsRenderPass)
void addResource(const sk_sp< const GrManagedResource > &resource)
void addGrBuffer(sk_sp< const GrBuffer > buffer)
void addGrSurface(sk_sp< const GrSurface > surface)
id< MTLBlitCommandEncoder > getBlitCommandEncoder()
void encodeWaitForEvent(sk_sp< GrMtlEvent >, uint64_t value)
static sk_sp< GrMtlCommandBuffer > Make(id< MTLCommandQueue > queue)
bool commit(bool waitUntilCompleted)
void addFinishedCallback(sk_sp< skgpu::RefCntedCallback > callback)
void encodeSignalEvent(sk_sp< GrMtlEvent >, uint64_t value)
void callFinishedCallbacks()
bool onCopySurface(GrSurface *dst, const SkIRect &dstRect, GrSurface *src, const SkIRect &srcRect, GrSamplerState::Filter) override
sk_sp< GrTexture > onCreateTexture(SkISize, const GrBackendFormat &, GrRenderable, int renderTargetSampleCnt, skgpu::Budgeted, GrProtected, int mipLevelCount, uint32_t levelClearMask, std::string_view label) override
sk_sp< GrThreadSafePipelineBuilder > refPipelineBuilder() override
std::unique_ptr< GrSemaphore > wrapBackendSemaphore(const GrBackendSemaphore &, GrSemaphoreWrapType, GrWrapOwnership) override
GrRingBuffer * uniformsRingBuffer() override
sk_sp< GrRenderTarget > onWrapBackendRenderTarget(const GrBackendRenderTarget &) override
sk_sp< GrTexture > onWrapBackendTexture(const GrBackendTexture &, GrWrapOwnership, GrWrapCacheable, GrIOType) override
GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Mipmapped, GrProtected) override
bool precompileShader(const SkData &key, const SkData &data) override
sk_sp< GrAttachment > makeMSAAAttachment(SkISize dimensions, const GrBackendFormat &format, int numSamples, GrProtected isProtected, GrMemoryless isMemoryless) override
GrBackendTexture onCreateBackendTexture(SkISize dimensions, const GrBackendFormat &, GrRenderable, skgpu::Mipmapped, GrProtected, std::string_view label) override
void onResolveRenderTarget(GrRenderTarget *target, const SkIRect &resolveRect) override
void takeOwnershipOfBuffer(sk_sp< GrGpuBuffer >) override
bool onTransferPixelsFrom(GrSurface *, SkIRect, GrColorType surfaceColorType, GrColorType bufferColorType, sk_sp< GrGpuBuffer >, size_t offset) override
bool onWritePixels(GrSurface *, SkIRect, GrColorType surfaceColorType, GrColorType bufferColorType, const GrMipLevel[], int mipLevelCount, bool prepForTexSampling) override
GrMtlRenderCommandEncoder * loadMSAAFromResolve(GrAttachment *dst, GrMtlAttachment *src, const SkIRect &srcRect, MTLRenderPassStencilAttachmentDescriptor *)
void insertSemaphore(GrSemaphore *semaphore) override
bool onTransferFromBufferToBuffer(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size) override
static std::unique_ptr< GrGpu > Make(const GrMtlBackendContext &, const GrContextOptions &, GrDirectContext *)
void copySurfaceAsBlit(GrSurface *dst, GrSurface *src, GrMtlAttachment *dstAttachment, GrMtlAttachment *srcAttachment, const SkIRect &srcRect, const SkIPoint &dstPoint)
GrMtlCommandBuffer * commandBuffer()
bool compile(const GrProgramDesc &, const GrProgramInfo &) override
void disconnect(DisconnectType) override
const GrMtlCaps & mtlCaps() const
sk_sp< GrTexture > onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Budgeted, skgpu::Mipmapped, GrProtected, const void *data, size_t dataSize) override
void copySurfaceAsResolve(GrSurface *dst, GrSurface *src)
void deleteBackendTexture(const GrBackendTexture &) override
std::unique_ptr< GrSemaphore > prepareTextureForCrossContextUsage(GrTexture *) override
void addFinishedProc(GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext) override
sk_sp< GrTexture > onWrapCompressedBackendTexture(const GrBackendTexture &, GrWrapOwnership, GrWrapCacheable) override
sk_sp< GrTexture > onWrapRenderableBackendTexture(const GrBackendTexture &, int sampleCnt, GrWrapOwnership, GrWrapCacheable) override
bool onSubmitToGpu(GrSyncCpu sync) override
GrOpsRenderPass * onGetOpsRenderPass(GrRenderTarget *, bool useMSAASurface, GrAttachment *, GrSurfaceOrigin, const SkIRect &, const GrOpsRenderPass::LoadAndStoreInfo &, const GrOpsRenderPass::StencilLoadAndStoreInfo &, const skia_private::TArray< GrSurfaceProxy *, true > &sampledProxies, GrXferBarrierFlags renderPassXferBarriers) override
void waitSemaphore(GrSemaphore *semaphore) override
id< MTLDevice > device() const
void finishOutstandingGpuWork() override
bool onTransferPixelsTo(GrTexture *, SkIRect, GrColorType textureColorType, GrColorType bufferColorType, sk_sp< GrGpuBuffer >, size_t offset, size_t rowBytes) override
bool onRegenerateMipMapLevels(GrTexture *) override
bool onUpdateCompressedBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, const void *data, size_t size) override
GrMtlResourceProvider & resourceProvider()
GrThreadSafePipelineBuilder * pipelineBuilder() override
void submit(GrOpsRenderPass *renderPass) override
sk_sp< GrAttachment > makeStencilAttachment(const GrBackendFormat &, SkISize dimensions, int numStencilSamples) override
bool onClearBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, std::array< float, 4 > color) override
bool onReadPixels(GrSurface *surface, SkIRect, GrColorType surfaceColorType, GrColorType bufferColorType, void *, size_t rowBytes) override
std::unique_ptr< GrSemaphore > makeSemaphore(bool isOwned) override
sk_sp< GrGpuBuffer > onCreateBuffer(size_t, GrGpuBufferType, GrAccessPattern) override
void setRenderPipelineState(id< MTLRenderPipelineState > pso)
void setLabel(NSString *label)
GrMtlAttachment * colorAttachment() const
static sk_sp< GrMtlRenderTarget > MakeWrappedRenderTarget(GrMtlGpu *, SkISize, int sampleCnt, id< MTLTexture >)
const GrMtlFramebuffer * getFramebuffer(bool withResolve, bool withStencil)
GrMtlAttachment * resolveAttachment() const
const GrMtlRenderPipeline * findOrCreateMSAALoadPipeline(MTLPixelFormat colorFormat, int sampleCount, MTLPixelFormat stencilFormat)
GrMtlPipelineState * findOrCreateCompatiblePipelineState(const GrProgramDesc &, const GrProgramInfo &, GrThreadSafePipelineBuilder::Stats::ProgramCacheResult *stat=nullptr)
bool precompileShader(const SkData &key, const SkData &data)
static std::unique_ptr< GrMtlSemaphore > Make(GrMtlGpu *gpu)
sk_sp< GrMtlEvent > event()
static std::unique_ptr< GrMtlSemaphore > MakeWrapped(GrMTLHandle mtlEvent, uint64_t value)
static sk_sp< GrMtlTextureRenderTarget > MakeNewTextureRenderTarget(GrMtlGpu *, skgpu::Budgeted, SkISize, int sampleCnt, MTLPixelFormat, uint32_t mipLevels, GrMipmapStatus, std::string_view label)
static sk_sp< GrMtlTextureRenderTarget > MakeWrappedTextureRenderTarget(GrMtlGpu *, SkISize, int sampleCnt, id< MTLTexture >, GrWrapCacheable)
static sk_sp< GrMtlTexture > MakeNewTexture(GrMtlGpu *, skgpu::Budgeted budgeted, SkISize dimensions, MTLPixelFormat format, uint32_t mipLevels, GrMipmapStatus, std::string_view label)
id< MTLTexture > mtlTexture() const
GrMtlAttachment * attachment() const
GrBackendFormat backendFormat() const override
static sk_sp< GrMtlTexture > MakeWrappedTexture(GrMtlGpu *, SkISize, id< MTLTexture >, GrWrapCacheable, GrIOType)
Slice suballocate(size_t size)
Slice allocateStagingBufferSlice(size_t size, size_t requiredAlignment=1)
SkISize dimensions() const
int maxMipmapLevel() const
const void * front() const
const void * back() const
void appendNString(char const (&value)[N])
void appendU32(uint32_t value)
void beginObject(const char *name=nullptr, bool multiline=true)
void appendU64(uint64_t value)
void appendBool(bool value)
void appendCString(const char *value)
static int ComputeLevelCount(int baseWidth, int baseHeight)
void reset(T *ptr=nullptr)
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
uint32_t uint32_t * format
static float max(float r, float g, float b)
SK_API bool GetMtlTextureInfo(const GrBackendRenderTarget &, GrMtlTextureInfo *)
SK_API GrBackendRenderTarget MakeMtl(int width, int height, const GrMtlTextureInfo &mtlInfo)
SK_API uint64_t GetMtlValue(const GrBackendSemaphore &)
SK_API GrMTLHandle GetMtlHandle(const GrBackendSemaphore &)
SK_API GrBackendTexture MakeMtl(int width, int height, skgpu::Mipmapped, const GrMtlTextureInfo &mtlInfo, std::string_view label={})
SK_API bool GetMtlTextureInfo(const GrBackendTexture &, GrMtlTextureInfo *)
sk_sp< SkBlender > blender SkRect rect
size_t CompressedRowBytes(SkTextureCompressionType type, int width)
bool MtlFormatIsCompressed(MTLPixelFormat mtlFormat)
size_t MtlFormatBytesPerBlock(MTLPixelFormat mtlFormat)
static void usage(char *argv0)
sk_cfp< GrMTLHandle > fDevice
sk_cfp< GrMTLHandle > fQueue
constexpr int32_t x() const
constexpr int32_t y() const
constexpr SkISize size() const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
constexpr SkIPoint topLeft() const
int32_t fLeft
smaller x-axis bounds
constexpr int32_t width() const
constexpr int32_t height() const