Enable MSAA for Metal.
Adds a separate resolve texture to GrMtlRenderTarget, which can be used to do a resolve for the main multisample color texture. The resolve is handled by setting a special Store action for the RenderCommandEncoder. Bug: skia:8243 Change-Id: I1ffd756c01a9b363116ffefee2c4c50ba9a3e637 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/225536 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
649774b686
commit
d361e64326
@ -59,6 +59,9 @@ public:
|
||||
int srcSampleCount, const SkIRect& srcRect, const SkIPoint& dstPoint,
|
||||
bool areDstSrcSameObj) const;
|
||||
|
||||
bool canCopyAsResolve(GrSurface* dst, int dstSampleCount, GrSurface* src, int srcSampleCount,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) const;
|
||||
|
||||
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
|
||||
bool* rectsMustMatch, bool* disallowSubrect) const override {
|
||||
return false;
|
||||
@ -104,9 +107,8 @@ private:
|
||||
kMSAA_Flag = 0x4,
|
||||
kResolve_Flag = 0x8,
|
||||
};
|
||||
// TODO: Put kMSAA_Flag back when MSAA is implemented
|
||||
static const uint16_t kAllFlags = kTextureable_Flag | kRenderable_Flag |
|
||||
/*kMSAA_Flag |*/ kResolve_Flag;
|
||||
kMSAA_Flag | kResolve_Flag;
|
||||
|
||||
uint16_t fFlags;
|
||||
};
|
||||
|
@ -37,7 +37,6 @@ GrMtlCaps::GrMtlCaps(const GrContextOptions& contextOptions, const id<MTLDevice>
|
||||
// doesn't support it.
|
||||
fFenceSyncSupport = false; // Fences are not implemented yet
|
||||
fSemaphoreSupport = false; // Semaphores are not implemented yet
|
||||
fMultisampleDisableSupport = true; // MSAA and resolving not implemented yet
|
||||
fCrossContextTextureSupport = false; // GrMtlGpu::prepareTextureForCrossContextUsage() not impl
|
||||
}
|
||||
|
||||
@ -137,6 +136,30 @@ bool GrMtlCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCount,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrMtlCaps::canCopyAsResolve(GrSurface* dst, int dstSampleCount,
|
||||
GrSurface* src, int srcSampleCount,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
|
||||
if (dst == src) {
|
||||
return false;
|
||||
}
|
||||
if (dst->backendFormat() != src->backendFormat()) {
|
||||
return false;
|
||||
}
|
||||
if (dstSampleCount > 1 || srcSampleCount == 1 || !src->asRenderTarget()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Support copying subrectangles
|
||||
if (dstPoint != SkIPoint::Make(0, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (srcRect != SkIRect::MakeXYWH(0, 0, src->width(), src->height())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrMtlCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
|
||||
int dstSampleCnt = 0;
|
||||
|
@ -59,8 +59,9 @@ static bool compatible(const MTLRenderPassAttachmentDescriptor* first,
|
||||
first.storeAction == MTLStoreActionDontCare;
|
||||
bool loadActionsValid = second.loadAction == MTLLoadActionLoad ||
|
||||
second.loadAction == MTLLoadActionDontCare;
|
||||
bool secondDoesntSampleFirst = !pipelineState ||
|
||||
pipelineState->doesntSampleAttachment(first);
|
||||
bool secondDoesntSampleFirst = (!pipelineState ||
|
||||
pipelineState->doesntSampleAttachment(first)) &&
|
||||
second.storeAction != MTLStoreActionMultisampleResolve;
|
||||
|
||||
return renderTargetsMatch &&
|
||||
(nil == first.texture ||
|
||||
@ -81,7 +82,9 @@ id<MTLRenderCommandEncoder> GrMtlCommandBuffer::getRenderCommandEncoder(
|
||||
|
||||
this->endAllEncoding();
|
||||
fActiveRenderCommandEncoder = [fCmdBuffer renderCommandEncoderWithDescriptor:descriptor];
|
||||
gpuCommandBuffer->initRenderState(fActiveRenderCommandEncoder);
|
||||
if (gpuCommandBuffer) {
|
||||
gpuCommandBuffer->initRenderState(fActiveRenderCommandEncoder);
|
||||
}
|
||||
fPreviousRenderPassDescriptor = descriptor;
|
||||
|
||||
return fActiveRenderCommandEncoder;
|
||||
|
@ -72,7 +72,9 @@ public:
|
||||
void testingOnly_flushGpuAndSync() override;
|
||||
#endif
|
||||
|
||||
bool copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
void copySurfaceAsResolve(GrSurface* dst, GrSurface* src);
|
||||
|
||||
void copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint);
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
@ -114,6 +116,10 @@ public:
|
||||
this->didWriteToSurface(surface, origin, bounds);
|
||||
}
|
||||
|
||||
void resolveRenderTargetNoFlush(GrRenderTarget* target) {
|
||||
this->internalResolveRenderTarget(target, false);
|
||||
}
|
||||
|
||||
private:
|
||||
GrMtlGpu(GrContext* context, const GrContextOptions& options,
|
||||
id<MTLDevice> device, id<MTLCommandQueue> queue, MTLFeatureSet featureSet);
|
||||
@ -171,7 +177,15 @@ private:
|
||||
|
||||
bool onRegenerateMipMapLevels(GrTexture*) override;
|
||||
|
||||
void onResolveRenderTarget(GrRenderTarget* target) override { return; }
|
||||
void onResolveRenderTarget(GrRenderTarget* target) override {
|
||||
// This resolve is called when we are preparing an msaa surface for external I/O. It is
|
||||
// called after flushing, so we need to make sure we submit the command buffer after doing
|
||||
// the resolve so that the resolve actually happens.
|
||||
this->internalResolveRenderTarget(target, true);
|
||||
}
|
||||
|
||||
void internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit);
|
||||
void resolveTexture(id<MTLTexture> colorTexture, id<MTLTexture> resolveTexture);
|
||||
|
||||
void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
|
||||
const GrFlushInfo& info, const GrPrepareForExternalIORequests&) override {
|
||||
|
@ -436,7 +436,6 @@ sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
|
||||
texDesc.mipmapLevelCount = mipLevels;
|
||||
texDesc.sampleCount = 1;
|
||||
texDesc.arrayLength = 1;
|
||||
texDesc.cpuCacheMode = MTLCPUCacheModeWriteCombined;
|
||||
// Make all textures have private gpu only access. We can use transfer buffers or textures
|
||||
// to copy to them.
|
||||
texDesc.storageMode = MTLStorageModePrivate;
|
||||
@ -455,10 +454,10 @@ sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
|
||||
}
|
||||
|
||||
if (renderTarget) {
|
||||
tex = GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted,
|
||||
desc, texDesc, mipMapsStatus);
|
||||
tex = GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(this, budgeted,
|
||||
desc, texDesc, mipMapsStatus);
|
||||
} else {
|
||||
tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, texDesc, mipMapsStatus);
|
||||
tex = GrMtlTexture::MakeNewTexture(this, budgeted, desc, texDesc, mipMapsStatus);
|
||||
}
|
||||
|
||||
if (!tex) {
|
||||
@ -863,7 +862,23 @@ static int get_surface_sample_cnt(GrSurface* surf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
void GrMtlGpu::copySurfaceAsResolve(GrSurface* dst, GrSurface* src) {
|
||||
// TODO: Add support for subrectangles
|
||||
GrMtlRenderTarget* srcRT = static_cast<GrMtlRenderTarget*>(src->asRenderTarget());
|
||||
GrRenderTarget* dstRT = dst->asRenderTarget();
|
||||
id<MTLTexture> dstTexture;
|
||||
if (dstRT) {
|
||||
GrMtlRenderTarget* mtlRT = static_cast<GrMtlRenderTarget*>(dstRT);
|
||||
dstTexture = mtlRT->mtlColorTexture();
|
||||
} else {
|
||||
SkASSERT(dst->asTexture());
|
||||
dstTexture = static_cast<GrMtlTexture*>(dst->asTexture())->mtlTexture();
|
||||
}
|
||||
|
||||
this->resolveTexture(dstTexture, srcRT->mtlColorTexture());
|
||||
}
|
||||
|
||||
void GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) {
|
||||
#ifdef SK_DEBUG
|
||||
int dstSampleCnt = get_surface_sample_cnt(dst);
|
||||
@ -871,8 +886,8 @@ bool GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect&
|
||||
SkASSERT(this->mtlCaps().canCopyAsBlit(dst->config(), dstSampleCnt, src->config(), srcSampleCnt,
|
||||
srcRect, dstPoint, dst == src));
|
||||
#endif
|
||||
id<MTLTexture> dstTex = GrGetMTLTextureFromSurface(dst, false);
|
||||
id<MTLTexture> srcTex = GrGetMTLTextureFromSurface(src, false);
|
||||
id<MTLTexture> dstTex = GrGetMTLTextureFromSurface(dst);
|
||||
id<MTLTexture> srcTex = GrGetMTLTextureFromSurface(src);
|
||||
|
||||
id<MTLBlitCommandEncoder> blitCmdEncoder = this->commandBuffer()->getBlitCommandEncoder();
|
||||
[blitCmdEncoder copyFromTexture: srcTex
|
||||
@ -884,12 +899,11 @@ bool GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect&
|
||||
destinationSlice: 0
|
||||
destinationLevel: 0
|
||||
destinationOrigin: MTLOriginMake(dstPoint.fX, dstPoint.fY, 0)];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) {
|
||||
SkASSERT(!src->isProtected() && !dst->isProtected());
|
||||
|
||||
GrPixelConfig dstConfig = dst->config();
|
||||
GrPixelConfig srcConfig = src->config();
|
||||
@ -897,15 +911,14 @@ bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcR
|
||||
int dstSampleCnt = get_surface_sample_cnt(dst);
|
||||
int srcSampleCnt = get_surface_sample_cnt(src);
|
||||
|
||||
if (dstSampleCnt > 1 || srcSampleCnt > 1) {
|
||||
SkASSERT(false); // Currently dont support MSAA. TODO: add copySurfaceAsResolve().
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
if (this->mtlCaps().canCopyAsBlit(dstConfig, dstSampleCnt, srcConfig, srcSampleCnt, srcRect,
|
||||
dstPoint, dst == src)) {
|
||||
success = this->copySurfaceAsBlit(dst, src, srcRect, dstPoint);
|
||||
if (this->mtlCaps().canCopyAsResolve(dst, dstSampleCnt, src, srcSampleCnt, srcRect, dstPoint)) {
|
||||
this->copySurfaceAsResolve(dst, src);
|
||||
success = true;
|
||||
} else if (this->mtlCaps().canCopyAsBlit(dstConfig, dstSampleCnt, srcConfig, srcSampleCnt,
|
||||
srcRect, dstPoint, dst == src)) {
|
||||
this->copySurfaceAsBlit(dst, src, srcRect, dstPoint);
|
||||
success = true;
|
||||
}
|
||||
if (success) {
|
||||
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
|
||||
@ -949,9 +962,32 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
|
||||
int bpp = GrColorTypeBytesPerPixel(dstColorType);
|
||||
size_t transBufferRowBytes = bpp * width;
|
||||
bool doResolve = get_surface_sample_cnt(surface) > 1;
|
||||
id<MTLTexture> mtlTexture = GrGetMTLTextureFromSurface(surface, doResolve);
|
||||
if (!mtlTexture || [mtlTexture isFramebufferOnly]) {
|
||||
|
||||
id<MTLTexture> mtlTexture;
|
||||
GrMtlRenderTarget* rt = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
|
||||
if (rt) {
|
||||
// resolve the render target if necessary
|
||||
switch (rt->getResolveType()) {
|
||||
case GrMtlRenderTarget::kCantResolve_ResolveType:
|
||||
return false;
|
||||
case GrMtlRenderTarget::kAutoResolves_ResolveType:
|
||||
mtlTexture = rt->mtlColorTexture();
|
||||
break;
|
||||
case GrMtlRenderTarget::kCanResolve_ResolveType:
|
||||
this->resolveRenderTargetNoFlush(rt);
|
||||
mtlTexture = rt->mtlResolveTexture();
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("Unknown resolve type");
|
||||
}
|
||||
} else {
|
||||
GrMtlTexture* texture = static_cast<GrMtlTexture*>(surface->asTexture());
|
||||
if (texture) {
|
||||
mtlTexture = texture->mtlTexture();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mtlTexture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -988,6 +1024,33 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, transBufferRowBytes, height);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void GrMtlGpu::internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit) {
|
||||
if (target->needsResolve()) {
|
||||
this->resolveTexture(static_cast<GrMtlRenderTarget*>(target)->mtlResolveTexture(),
|
||||
static_cast<GrMtlRenderTarget*>(target)->mtlColorTexture());
|
||||
target->flagAsResolved();
|
||||
|
||||
if (requiresSubmit) {
|
||||
this->submitCommandBuffer(kSkip_SyncQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrMtlGpu::resolveTexture(id<MTLTexture> resolveTexture, id<MTLTexture> colorTexture) {
|
||||
auto renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
renderPassDesc.colorAttachments[0].texture = colorTexture;
|
||||
renderPassDesc.colorAttachments[0].slice = 0;
|
||||
renderPassDesc.colorAttachments[0].level = 0;
|
||||
renderPassDesc.colorAttachments[0].resolveTexture = resolveTexture;
|
||||
renderPassDesc.colorAttachments[0].slice = 0;
|
||||
renderPassDesc.colorAttachments[0].level = 0;
|
||||
renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionLoad;
|
||||
renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve;
|
||||
|
||||
id<MTLRenderCommandEncoder> cmdEncoder =
|
||||
this->commandBuffer()->getRenderCommandEncoder(renderPassDesc, nullptr, nullptr);
|
||||
SkASSERT(nil != cmdEncoder);
|
||||
cmdEncoder.label = @"resolveTexture";
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/gpu/mtl/GrMtlPipelineState.h"
|
||||
#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
|
||||
#include "src/gpu/mtl/GrMtlRenderTarget.h"
|
||||
#include "src/gpu/mtl/GrMtlTexture.h"
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This file must be compiled with Arc. Use -fobjc-arc flag
|
||||
@ -113,6 +114,13 @@ void GrMtlGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
}
|
||||
|
||||
auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) {
|
||||
GrMtlTexture* mtlTexture = static_cast<GrMtlTexture*>(texture);
|
||||
// We may need to resolve the texture first if it is also a render target
|
||||
GrMtlRenderTarget* texRT = static_cast<GrMtlRenderTarget*>(mtlTexture->asRenderTarget());
|
||||
if (texRT) {
|
||||
fGpu->resolveRenderTargetNoFlush(texRT);
|
||||
}
|
||||
|
||||
// Check if we need to regenerate any mip maps
|
||||
if (GrSamplerState::Filter::kMipMap == filter &&
|
||||
(texture->width() != 1 || texture->height() != 1)) {
|
||||
@ -238,6 +246,7 @@ void GrMtlGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool i
|
||||
}
|
||||
|
||||
void GrMtlGpuRTCommandBuffer::initRenderState(id<MTLRenderCommandEncoder> encoder) {
|
||||
[encoder pushDebugGroup:@"initRenderState"];
|
||||
[encoder setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||
// Strictly speaking we shouldn't have to set this, as the default viewport is the size of
|
||||
// the drawable used to generate the renderCommandEncoder -- but just in case.
|
||||
@ -246,6 +255,7 @@ void GrMtlGpuRTCommandBuffer::initRenderState(id<MTLRenderCommandEncoder> encode
|
||||
0.0, 1.0 };
|
||||
[encoder setViewport:viewport];
|
||||
this->resetBufferBindings();
|
||||
[encoder popDebugGroup];
|
||||
}
|
||||
|
||||
void GrMtlGpuRTCommandBuffer::setupRenderPass(
|
||||
@ -273,7 +283,7 @@ void GrMtlGpuRTCommandBuffer::setupRenderPass(
|
||||
|
||||
auto renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
renderPassDesc.colorAttachments[0].texture =
|
||||
static_cast<GrMtlRenderTarget*>(fRenderTarget)->mtlRenderTexture();
|
||||
static_cast<GrMtlRenderTarget*>(fRenderTarget)->mtlColorTexture();
|
||||
renderPassDesc.colorAttachments[0].slice = 0;
|
||||
renderPassDesc.colorAttachments[0].level = 0;
|
||||
const SkPMColor4f& clearColor = colorInfo.fClearColor;
|
||||
|
@ -116,9 +116,11 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
void GrMtlPipelineState::setDrawState(id<MTLRenderCommandEncoder> renderCmdEncoder,
|
||||
const GrSwizzle& outputSwizzle,
|
||||
const GrXferProcessor& xferProcessor) {
|
||||
[renderCmdEncoder pushDebugGroup:@"setDrawState"];
|
||||
this->bind(renderCmdEncoder);
|
||||
this->setBlendConstants(renderCmdEncoder, outputSwizzle, xferProcessor);
|
||||
this->setDepthStencilState(renderCmdEncoder);
|
||||
[renderCmdEncoder popDebugGroup];
|
||||
}
|
||||
|
||||
void GrMtlPipelineState::bind(id<MTLRenderCommandEncoder> renderCmdEncoder) {
|
||||
|
@ -370,6 +370,7 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||
pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc);
|
||||
pipelineDescriptor.colorAttachments[0] = create_color_attachment(this->config(), pipeline);
|
||||
pipelineDescriptor.sampleCount = renderTarget->numSamples();
|
||||
bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
|
||||
GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
|
||||
pipelineDescriptor.stencilAttachmentPixelFormat =
|
||||
|
@ -26,20 +26,18 @@ public:
|
||||
|
||||
// override of GrRenderTarget
|
||||
ResolveType getResolveType() const override {
|
||||
return kCantResolve_ResolveType;
|
||||
#if 0 // TODO figure this once we support msaa
|
||||
if (this->numSamples() > 1) {
|
||||
return kCanResolve_ResolveType;
|
||||
}
|
||||
return kAutoResolves_ResolveType;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
id<MTLTexture> mtlRenderTexture() const { return fRenderTexture; }
|
||||
id<MTLTexture> mtlColorTexture() const { return fColorTexture; }
|
||||
id<MTLTexture> mtlResolveTexture() const { return fResolveTexture; }
|
||||
|
||||
GrBackendRenderTarget getBackendRenderTarget() const override;
|
||||
|
||||
@ -48,7 +46,12 @@ public:
|
||||
protected:
|
||||
GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture);
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture);
|
||||
|
||||
GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture);
|
||||
|
||||
GrMtlGpu* getMtlGpu() const;
|
||||
|
||||
@ -68,7 +71,7 @@ protected:
|
||||
numColorSamples, GrMipMapped::kNo);
|
||||
}
|
||||
|
||||
id<MTLTexture> fRenderTexture;
|
||||
id<MTLTexture> fColorTexture;
|
||||
id<MTLTexture> fResolveTexture;
|
||||
|
||||
private:
|
||||
@ -76,7 +79,12 @@ private:
|
||||
enum Wrapped { kWrapped };
|
||||
GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
Wrapped);
|
||||
GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture,
|
||||
Wrapped);
|
||||
|
||||
bool completeStencilAttachment() override;
|
||||
|
@ -17,11 +17,24 @@
|
||||
// Called for wrapped non-texture render targets.
|
||||
GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
Wrapped)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrRenderTarget(gpu, desc)
|
||||
, fRenderTexture(renderTexture)
|
||||
, fColorTexture(colorTexture)
|
||||
, fResolveTexture(resolveTexture) {
|
||||
SkASSERT(desc.fSampleCnt > 1);
|
||||
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
|
||||
}
|
||||
|
||||
GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture,
|
||||
Wrapped)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrRenderTarget(gpu, desc)
|
||||
, fColorTexture(colorTexture)
|
||||
, fResolveTexture(nil) {
|
||||
SkASSERT(1 == desc.fSampleCnt);
|
||||
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
|
||||
@ -30,36 +43,76 @@ GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
// Called by subclass constructors.
|
||||
GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture)
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrRenderTarget(gpu, desc)
|
||||
, fRenderTexture(renderTexture)
|
||||
, fColorTexture(colorTexture)
|
||||
, fResolveTexture(resolveTexture) {
|
||||
SkASSERT(desc.fSampleCnt > 1);
|
||||
}
|
||||
|
||||
GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrRenderTarget(gpu, desc)
|
||||
, fColorTexture(colorTexture)
|
||||
, fResolveTexture(nil) {
|
||||
SkASSERT(1 == desc.fSampleCnt);
|
||||
}
|
||||
|
||||
sk_sp<GrMtlRenderTarget>
|
||||
GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu, const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture) {
|
||||
SkASSERT(nil != renderTexture);
|
||||
SkASSERT(1 == renderTexture.mipmapLevelCount);
|
||||
SkASSERT(MTLTextureUsageRenderTarget & renderTexture.usage);
|
||||
return sk_sp<GrMtlRenderTarget>(new GrMtlRenderTarget(gpu, desc, renderTexture, kWrapped));
|
||||
id<MTLTexture> texture) {
|
||||
SkASSERT(nil != texture);
|
||||
SkASSERT(1 == texture.mipmapLevelCount);
|
||||
SkASSERT(MTLTextureUsageRenderTarget & texture.usage);
|
||||
|
||||
GrMtlRenderTarget* mtlRT;
|
||||
if (desc.fSampleCnt > 1) {
|
||||
MTLPixelFormat format;
|
||||
if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
|
||||
return nullptr;
|
||||
}
|
||||
MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
|
||||
texDesc.textureType = MTLTextureType2DMultisample;
|
||||
texDesc.pixelFormat = format;
|
||||
texDesc.width = desc.fWidth;
|
||||
texDesc.height = desc.fHeight;
|
||||
texDesc.depth = 1;
|
||||
texDesc.mipmapLevelCount = 1;
|
||||
texDesc.sampleCount = desc.fSampleCnt;
|
||||
texDesc.arrayLength = 1;
|
||||
texDesc.storageMode = MTLStorageModePrivate;
|
||||
texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
|
||||
|
||||
id<MTLTexture> colorTexture = [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
if (!colorTexture) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
|
||||
mtlRT = new GrMtlRenderTarget(gpu, desc, colorTexture, texture, kWrapped);
|
||||
} else {
|
||||
mtlRT = new GrMtlRenderTarget(gpu, desc, texture, kWrapped);
|
||||
}
|
||||
|
||||
return sk_sp<GrMtlRenderTarget>(mtlRT);
|
||||
}
|
||||
|
||||
GrMtlRenderTarget::~GrMtlRenderTarget() {
|
||||
SkASSERT(nil == fRenderTexture);
|
||||
SkASSERT(nil == fColorTexture);
|
||||
SkASSERT(nil == fResolveTexture);
|
||||
}
|
||||
|
||||
GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const {
|
||||
GrMtlTextureInfo info;
|
||||
info.fTexture.reset(GrRetainPtrFromId(fRenderTexture));
|
||||
return GrBackendRenderTarget(this->width(), this->height(), fRenderTexture.sampleCount, info);
|
||||
info.fTexture.reset(GrRetainPtrFromId(fColorTexture));
|
||||
return GrBackendRenderTarget(this->width(), this->height(), fColorTexture.sampleCount, info);
|
||||
}
|
||||
|
||||
GrBackendFormat GrMtlRenderTarget::backendFormat() const {
|
||||
return GrBackendFormat::MakeMtl(fRenderTexture.pixelFormat);
|
||||
return GrBackendFormat::MakeMtl(fColorTexture.pixelFormat);
|
||||
}
|
||||
|
||||
GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
|
||||
@ -68,13 +121,13 @@ GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
|
||||
}
|
||||
|
||||
void GrMtlRenderTarget::onAbandon() {
|
||||
fRenderTexture = nil;
|
||||
fColorTexture = nil;
|
||||
fResolveTexture = nil;
|
||||
INHERITED::onAbandon();
|
||||
}
|
||||
|
||||
void GrMtlRenderTarget::onRelease() {
|
||||
fRenderTexture = nil;
|
||||
fColorTexture = nil;
|
||||
fResolveTexture = nil;
|
||||
INHERITED::onRelease();
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ GrMtlStencilAttachment* GrMtlStencilAttachment::Create(GrMtlGpu* gpu,
|
||||
mipmapped:NO];
|
||||
desc.resourceOptions = MTLResourceStorageModePrivate;
|
||||
desc.usage = MTLTextureUsageRenderTarget;
|
||||
desc.sampleCount = sampleCnt;
|
||||
if (sampleCnt > 1) {
|
||||
desc.textureType = MTLTextureType2DMultisample;
|
||||
}
|
||||
return new GrMtlStencilAttachment(gpu, format, [gpu->device() newTextureWithDescriptor:desc]);
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,10 @@ class GrMtlGpu;
|
||||
|
||||
class GrMtlTexture : public GrTexture {
|
||||
public:
|
||||
static sk_sp<GrMtlTexture> CreateNewTexture(GrMtlGpu*, SkBudgeted budgeted,
|
||||
const GrSurfaceDesc&,
|
||||
MTLTextureDescriptor*,
|
||||
GrMipMapsStatus);
|
||||
static sk_sp<GrMtlTexture> MakeNewTexture(GrMtlGpu*, SkBudgeted budgeted,
|
||||
const GrSurfaceDesc&,
|
||||
MTLTextureDescriptor*,
|
||||
GrMipMapsStatus);
|
||||
|
||||
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&, id<MTLTexture>,
|
||||
GrWrapCacheable, GrIOType);
|
||||
|
@ -54,16 +54,14 @@ GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
|
||||
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount));
|
||||
}
|
||||
|
||||
sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted,
|
||||
sk_sp<GrMtlTexture> GrMtlTexture::MakeNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
MTLTextureDescriptor* texDesc,
|
||||
GrMipMapsStatus mipMapsStatus) {
|
||||
if (desc.fSampleCnt > 1) {
|
||||
SkASSERT(false); // Currently we don't support msaa
|
||||
id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
SkASSERT(nil != texture);
|
||||
SkASSERT(MTLTextureUsageShaderRead & texture.usage);
|
||||
return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipMapsStatus));
|
||||
}
|
||||
@ -73,10 +71,6 @@ sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu,
|
||||
id<MTLTexture> texture,
|
||||
GrWrapCacheable cacheable,
|
||||
GrIOType ioType) {
|
||||
if (desc.fSampleCnt > 1) {
|
||||
SkASSERT(false); // Currently we don't support msaa
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(nil != texture);
|
||||
SkASSERT(MTLTextureUsageShaderRead & texture.usage);
|
||||
GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1 ? GrMipMapsStatus::kValid
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
class GrMtlTextureRenderTarget: public GrMtlTexture, public GrMtlRenderTarget {
|
||||
public:
|
||||
static sk_sp<GrMtlTextureRenderTarget> CreateNewTextureRenderTarget(GrMtlGpu*,
|
||||
SkBudgeted,
|
||||
const GrSurfaceDesc&,
|
||||
MTLTextureDescriptor*,
|
||||
GrMipMapsStatus);
|
||||
static sk_sp<GrMtlTextureRenderTarget> MakeNewTextureRenderTarget(GrMtlGpu*,
|
||||
SkBudgeted,
|
||||
const GrSurfaceDesc&,
|
||||
MTLTextureDescriptor*,
|
||||
GrMipMapsStatus);
|
||||
|
||||
static sk_sp<GrMtlTextureRenderTarget> MakeWrappedTextureRenderTarget(GrMtlGpu*,
|
||||
const GrSurfaceDesc&,
|
||||
@ -42,25 +42,26 @@ private:
|
||||
GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
GrMipMapsStatus);
|
||||
|
||||
GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
GrMipMapsStatus);
|
||||
|
||||
GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
GrMipMapsStatus);
|
||||
GrMipMapsStatus,
|
||||
GrWrapCacheable cacheable);
|
||||
|
||||
GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
GrMipMapsStatus,
|
||||
GrWrapCacheable cacheable);
|
||||
|
||||
|
@ -16,54 +16,117 @@
|
||||
GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrMtlTexture(gpu, desc, renderTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, renderTexture) {
|
||||
, GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, colorTexture, resolveTexture) {
|
||||
this->registerWithCache(budgeted);
|
||||
}
|
||||
|
||||
GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrMtlTexture(gpu, desc, colorTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, colorTexture) {
|
||||
this->registerWithCache(budgeted);
|
||||
}
|
||||
|
||||
GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> colorTexture,
|
||||
id<MTLTexture> resolveTexture,
|
||||
GrMipMapsStatus mipMapsStatus,
|
||||
GrWrapCacheable cacheable)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrMtlTexture(gpu, desc, renderTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, renderTexture) {
|
||||
, GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, colorTexture, resolveTexture) {
|
||||
this->registerWithCacheWrapped(cacheable);
|
||||
}
|
||||
|
||||
sk_sp<GrMtlTextureRenderTarget>
|
||||
GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
MTLTextureDescriptor* texDesc,
|
||||
GrMipMapsStatus mipMapsStatus) {
|
||||
id<MTLTexture> renderTexture = [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
SkASSERT(nil != renderTexture);
|
||||
if (desc.fSampleCnt > 1) {
|
||||
GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> colorTexture,
|
||||
GrMipMapsStatus mipMapsStatus,
|
||||
GrWrapCacheable cacheable)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrMtlTexture(gpu, desc, colorTexture, mipMapsStatus)
|
||||
, GrMtlRenderTarget(gpu, desc, colorTexture) {
|
||||
this->registerWithCacheWrapped(cacheable);
|
||||
}
|
||||
|
||||
id<MTLTexture> create_msaa_texture(GrMtlGpu* gpu, const GrSurfaceDesc& desc) {
|
||||
MTLPixelFormat format;
|
||||
if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & renderTexture.usage);
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, budgeted, desc, renderTexture, mipMapsStatus));
|
||||
MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
|
||||
texDesc.textureType = MTLTextureType2DMultisample;
|
||||
texDesc.pixelFormat = format;
|
||||
texDesc.width = desc.fWidth;
|
||||
texDesc.height = desc.fHeight;
|
||||
texDesc.depth = 1;
|
||||
texDesc.mipmapLevelCount = 1;
|
||||
texDesc.sampleCount = desc.fSampleCnt;
|
||||
texDesc.arrayLength = 1;
|
||||
texDesc.storageMode = MTLStorageModePrivate;
|
||||
texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
|
||||
|
||||
return [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
}
|
||||
|
||||
sk_sp<GrMtlTextureRenderTarget>
|
||||
GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(GrMtlGpu* gpu,
|
||||
SkBudgeted budgeted,
|
||||
const GrSurfaceDesc& desc,
|
||||
MTLTextureDescriptor* texDesc,
|
||||
GrMipMapsStatus mipMapsStatus) {
|
||||
id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc];
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
|
||||
|
||||
if (desc.fSampleCnt > 1) {
|
||||
id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc);
|
||||
if (!colorTexture) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, budgeted, desc, colorTexture, texture,
|
||||
mipMapsStatus));
|
||||
} else {
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, budgeted, desc, texture, mipMapsStatus));
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
|
||||
GrMtlGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
id<MTLTexture> renderTexture,
|
||||
id<MTLTexture> texture,
|
||||
GrWrapCacheable cacheable) {
|
||||
SkASSERT(nil != renderTexture);
|
||||
GrMipMapsStatus mipMapsStatus = renderTexture.mipmapLevelCount > 1
|
||||
SkASSERT(nil != texture);
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
|
||||
GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1
|
||||
? GrMipMapsStatus::kDirty
|
||||
: GrMipMapsStatus::kNotAllocated;
|
||||
if (desc.fSampleCnt > 1) {
|
||||
return nullptr;
|
||||
id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc);
|
||||
if (!colorTexture) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, desc, colorTexture, texture, mipMapsStatus,
|
||||
cacheable));
|
||||
} else {
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, desc, texture, mipMapsStatus, cacheable));
|
||||
}
|
||||
SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & renderTexture.usage);
|
||||
return sk_sp<GrMtlTextureRenderTarget>(
|
||||
new GrMtlTextureRenderTarget(gpu, desc, renderTexture, mipMapsStatus, cacheable));
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ id<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
|
||||
id<MTLDevice>, MTLRenderPipelineDescriptor*, bool* timedout);
|
||||
|
||||
/**
|
||||
* Returns a MTLTexture corresponding to the GrSurface. Optionally can do a resolve.
|
||||
* Returns a MTLTexture corresponding to the GrSurface.
|
||||
*/
|
||||
id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface, bool doResolve);
|
||||
id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface);
|
||||
|
||||
#endif
|
||||
|
@ -257,19 +257,18 @@ id<MTLRenderPipelineState> GrMtlNewRenderPipelineStateWithDescriptor(
|
||||
return pipelineState;
|
||||
}
|
||||
|
||||
id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface, bool doResolve) {
|
||||
id<MTLTexture> GrGetMTLTextureFromSurface(GrSurface* surface) {
|
||||
id<MTLTexture> mtlTexture = nil;
|
||||
|
||||
GrMtlRenderTarget* renderTarget = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget());
|
||||
GrMtlTexture* texture;
|
||||
if (renderTarget) {
|
||||
if (doResolve) {
|
||||
// TODO: do resolve and set mtlTexture to resolved texture. As of now, we shouldn't
|
||||
// have any multisampled render targets.
|
||||
// We should not be using this for multisampled rendertargets
|
||||
if (renderTarget->numSamples() > 1) {
|
||||
SkASSERT(false);
|
||||
} else {
|
||||
mtlTexture = renderTarget->mtlRenderTexture();
|
||||
return nil;
|
||||
}
|
||||
mtlTexture = renderTarget->mtlColorTexture();
|
||||
} else {
|
||||
texture = static_cast<GrMtlTexture*>(surface->asTexture());
|
||||
if (texture) {
|
||||
|
@ -39,8 +39,7 @@ void MetalWindowContext::initializeContext() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO: Multisampling not supported
|
||||
fSampleCount = 1; //fDisplayParams.fMSAASampleCount;
|
||||
fSampleCount = fDisplayParams.fMSAASampleCount;
|
||||
fStencilBits = 8;
|
||||
|
||||
fMetalLayer = [CAMetalLayer layer];
|
||||
@ -86,16 +85,28 @@ sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
|
||||
GrMtlTextureInfo fbInfo;
|
||||
fbInfo.fTexture.retain((__bridge const void*)(fCurrentDrawable.texture));
|
||||
|
||||
GrBackendRenderTarget backendRT(fWidth,
|
||||
fHeight,
|
||||
fSampleCount,
|
||||
fbInfo);
|
||||
if (fSampleCount == 1) {
|
||||
GrBackendRenderTarget backendRT(fWidth,
|
||||
fHeight,
|
||||
fSampleCount,
|
||||
fbInfo);
|
||||
|
||||
surface = SkSurface::MakeFromBackendRenderTarget(fContext.get(), backendRT,
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
kBGRA_8888_SkColorType,
|
||||
fDisplayParams.fColorSpace,
|
||||
&fDisplayParams.fSurfaceProps);
|
||||
surface = SkSurface::MakeFromBackendRenderTarget(fContext.get(), backendRT,
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
kBGRA_8888_SkColorType,
|
||||
fDisplayParams.fColorSpace,
|
||||
&fDisplayParams.fSurfaceProps);
|
||||
} else {
|
||||
GrBackendTexture backendTexture(fWidth,
|
||||
fHeight,
|
||||
GrMipMapped::kNo,
|
||||
fbInfo);
|
||||
|
||||
surface = SkSurface::MakeFromBackendTexture(
|
||||
fContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, fSampleCount,
|
||||
kBGRA_8888_SkColorType, fDisplayParams.fColorSpace,
|
||||
&fDisplayParams.fSurfaceProps);
|
||||
}
|
||||
}
|
||||
|
||||
return surface;
|
||||
|
@ -19,8 +19,7 @@ class Window_mac : public Window {
|
||||
public:
|
||||
Window_mac()
|
||||
: INHERITED()
|
||||
, fWindow(nil)
|
||||
, fMSAASampleCount(1) {}
|
||||
, fWindow(nil) {}
|
||||
~Window_mac() override {
|
||||
this->closeWindow();
|
||||
}
|
||||
@ -50,7 +49,6 @@ public:
|
||||
private:
|
||||
NSWindow* fWindow;
|
||||
NSInteger fWindowNumber;
|
||||
int fMSAASampleCount;
|
||||
|
||||
static SkTDynamicHash<Window_mac, NSInteger> gWindowMap;
|
||||
|
||||
|
@ -41,10 +41,6 @@ Window* Window::CreateNativeWindow(void*) {
|
||||
}
|
||||
|
||||
bool Window_mac::initWindow() {
|
||||
if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
|
||||
this->closeWindow();
|
||||
}
|
||||
|
||||
// we already have a window
|
||||
if (fWindow) {
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user