2019-11-11 21:14:13 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2019 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "include/core/SkSurface.h"
|
2020-07-06 14:56:46 +00:00
|
|
|
#include "include/gpu/GrDirectContext.h"
|
2020-10-14 15:23:11 +00:00
|
|
|
#include "src/gpu/GrDirectContextPriv.h"
|
2020-04-06 17:57:30 +00:00
|
|
|
#include "src/gpu/GrProxyProvider.h"
|
2019-11-11 21:14:13 +00:00
|
|
|
#include "src/gpu/mtl/GrMtlGpu.h"
|
|
|
|
#include "tests/Test.h"
|
|
|
|
|
|
|
|
#import <Metal/Metal.h>
|
|
|
|
#import <MetalKit/MTKView.h>
|
|
|
|
|
|
|
|
#include "src/gpu/mtl/GrMtlCaps.h"
|
|
|
|
#include "src/gpu/mtl/GrMtlTextureRenderTarget.h"
|
|
|
|
|
|
|
|
DEF_GPUTEST_FOR_METAL_CONTEXT(MtlCopySurfaceTest, reporter, ctxInfo) {
|
2021-09-14 12:36:55 +00:00
|
|
|
if (@available(macOS 11.0, iOS 9.0, *)) {
|
|
|
|
static const int kWidth = 1024;
|
|
|
|
static const int kHeight = 768;
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
auto context = ctxInfo.directContext();
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
// This is a bit weird, but it's the only way to get a framebufferOnly surface
|
|
|
|
GrMtlGpu* gpu = (GrMtlGpu*) context->priv().getGpu();
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
MTKView* view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, kWidth, kHeight)
|
|
|
|
device:gpu->device()];
|
|
|
|
id<CAMetalDrawable> drawable = [view currentDrawable];
|
|
|
|
REPORTER_ASSERT(reporter, drawable.texture.framebufferOnly);
|
|
|
|
REPORTER_ASSERT(reporter, drawable.texture.usage & MTLTextureUsageRenderTarget);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
// Test to see if we can initiate a copy via GrSurfaceProxys
|
|
|
|
SkSurfaceProps props(0, kRGB_H_SkPixelGeometry);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
// TODO: check multisampled RT as well
|
|
|
|
GrMtlTextureInfo fbInfo;
|
|
|
|
fbInfo.fTexture.retain((__bridge const void*)(drawable.texture));
|
|
|
|
GrBackendRenderTarget backendRT(kWidth, kHeight, fbInfo);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
|
|
|
sk_sp<GrSurfaceProxy> srcProxy = proxyProvider->wrapBackendRenderTarget(backendRT, nullptr);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
auto dstProxy = GrSurfaceProxy::Copy(context,
|
|
|
|
srcProxy,
|
|
|
|
kTopLeft_GrSurfaceOrigin,
|
|
|
|
GrMipmapped::kNo,
|
|
|
|
SkBackingFit::kExact,
|
|
|
|
SkBudgeted::kYes);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
// TODO: GrSurfaceProxy::Copy doesn't check to see if the framebufferOnly bit is set yet.
|
|
|
|
// Update this when it does -- it should fail.
|
|
|
|
if (!dstProxy) {
|
|
|
|
ERRORF(reporter, "Expected copy to succeed");
|
|
|
|
}
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
// Try direct copy via GPU (should fail)
|
|
|
|
GrBackendFormat backendFormat = GrBackendFormat::MakeMtl(drawable.texture.pixelFormat);
|
|
|
|
GrSurface* src = srcProxy->peekSurface();
|
|
|
|
sk_sp<GrTexture> dst =
|
|
|
|
gpu->createTexture({kWidth, kHeight}, backendFormat, GrTextureType::k2D,
|
|
|
|
GrRenderable::kNo, 1, GrMipmapped::kNo, SkBudgeted::kNo,
|
|
|
|
GrProtected::kNo);
|
2019-11-11 21:14:13 +00:00
|
|
|
|
2021-09-14 12:36:55 +00:00
|
|
|
bool result = gpu->copySurface(dst.get(), src, SkIRect::MakeXYWH(0, 0, kWidth, kHeight),
|
|
|
|
SkIPoint::Make(0, 0));
|
|
|
|
REPORTER_ASSERT(reporter, !result);
|
|
|
|
}
|
2019-11-11 21:14:13 +00:00
|
|
|
}
|