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,
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() {
131 this->submitCommandBuffer(SyncQueue::kForce_SyncQueue);
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()) {
213 if (sync == SyncQueue::kForce_SyncQueue) {
215 this->checkForFinishedCommandBuffers();
219 if (fCurrentCmdBuffer) {
226 bool didCommit = fCurrentCmdBuffer->
commit(sync == SyncQueue::kForce_SyncQueue);
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);
292bool GrMtlGpu::onSubmitToGpu(
GrSyncCpu sync) {
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;
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);
547 SkASSERT(pixelFormat != MTLPixelFormatInvalid);
558 int renderTargetSampleCnt,
562 uint32_t levelClearMask,
563 std::string_view label) {
571 SkASSERT(mtlPixelFormat != MTLPixelFormatInvalid);
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);
621 int numMipLevels = 1;
631 numMipLevels, mipmapStatus,
632 "MtlGpu_CreateCompressedTexture");
638 id<MTLTexture> GR_NORETAIN mtlTexture = tex->mtlTexture();
648 &individualMipOffsets,
651 SkASSERT(dataSize == combinedBufferSize);
657 dataSize, alignment);
658 if (!slice.fBuffer) {
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];
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,
869 const size_t trimRB = srcData[
level].
width() * bytesPerPixel;
877bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat mtlFormat,
883 GrMtlTextureInfo*
info) {
897 auto desc = [[MTLTextureDescriptor alloc]
init];
898 desc.pixelFormat = mtlFormat;
904 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
905 desc.storageMode = MTLStorageModePrivate;
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);
969 auto rb = ii.minRowBytes();
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),
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,
1042bool GrMtlGpu::onUpdateCompressedBackendTexture(
const GrBackendTexture& backendTexture,
1046 GrMtlTextureInfo
info;
1051 int numMipLevels = mtlTexture.mipmapLevelCount;
1060 size_t combinedBufferSize;
1063 &individualMipOffsets,
1068 this->
mtlCaps().getMinBufferAlignment());
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),
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()) {
1184 if (sampleCnt == 0) {
1188 GrMtlTextureInfo
info;
1189 if (!this->createMtlTextureForBackendSurface(
format,
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();
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];
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,
1323 dstAttachment == srcAttachment)) {
1332 if (this->
mtlCaps().canCopyAsBlit(dstFormat, dstSampleCnt, srcFormat, srcSampleCnt,
1333 srcRect, dstPoint, dstAttachment == srcAttachment)) {
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();
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];
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);
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();
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)
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
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
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)
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)
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
#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)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
static constexpr bool SkToBool(const T &x)
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)
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< GrThreadSafePipelineBuilder > refPipelineBuilder() override
std::unique_ptr< GrSemaphore > wrapBackendSemaphore(const GrBackendSemaphore &, GrSemaphoreWrapType, GrWrapOwnership) override
GrRingBuffer * uniformsRingBuffer() override
bool precompileShader(const SkData &key, const SkData &data) override
GrMtlRenderCommandEncoder * loadMSAAFromResolve(GrAttachment *dst, GrMtlAttachment *src, const SkIRect &srcRect, MTLRenderPassStencilAttachmentDescriptor *)
void insertSemaphore(GrSemaphore *semaphore) 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
void copySurfaceAsResolve(GrSurface *dst, GrSurface *src)
void deleteBackendTexture(const GrBackendTexture &) override
std::unique_ptr< GrSemaphore > prepareTextureForCrossContextUsage(GrTexture *) override
void waitSemaphore(GrSemaphore *semaphore) override
id< MTLDevice > device() const
void finishOutstandingGpuWork() override
GrMtlResourceProvider & resourceProvider()
GrThreadSafePipelineBuilder * pipelineBuilder() override
void submit(GrOpsRenderPass *renderPass) override
std::unique_ptr< GrSemaphore > makeSemaphore(bool isOwned) 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)
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 *)
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
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
std::shared_ptr< const fml::Mapping > data