Set up prototype interface for MakeFromCAMetalLayer

Change-Id: I87b0fc76ef48c1a21498e576853a6c3b4a6a98f9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/242563
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Jim Van Verth 2019-09-19 13:03:09 -04:00 committed by Skia Commit-Bot
parent c766d7fe3d
commit b2f55532bb
5 changed files with 118 additions and 32 deletions

View File

@ -3,6 +3,7 @@ Skia Graphics Release Notes
This file includes a list of high level updates for each milestone release.
-----
* Add SkSurface::MakeFromCAMetalLayer
* Remove isRectContour and ksNestedFillRects from public
* Start to move nested SkPath types (e.g. Direction, Verb) up to root level in SkPathTypes.h

View File

@ -784,6 +784,7 @@ skia_metal_sources = [
"$_src/gpu/mtl/GrMtlUtil.mm",
"$_src/gpu/mtl/GrMtlVaryingHandler.h",
"$_src/gpu/mtl/GrMtlVaryingHandler.mm",
"$_src/image/SkSurface_GpuMtl.mm",
]
skia_native_gpu_sources = [

View File

@ -18,6 +18,10 @@
#include <android/hardware_buffer.h>
#endif
#ifdef SK_METAL
#include "include/gpu/mtl/GrMtlTypes.h"
#endif
class SkCanvas;
class SkDeferredDisplayList;
class SkPaint;
@ -295,7 +299,7 @@ public:
Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
Currently this is only supported for buffers that can be textured as well as rendered to.
In other workds that must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
In other words that must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE usage bits.
@param context GPU context
@ -313,6 +317,45 @@ public:
const SkSurfaceProps* surfaceProps);
#endif
#ifdef SK_METAL
/** Private.
Creates SkSurface from CAMetalLayer.
Returned SkSurface takes a reference on the CAMetalLayer. The ref on the layer will be
released when the SkSurface is destroyed.
Only available when Metal API is enabled.
Will grab the current drawable from the layer and use its texture as a backendRT to
create a renderable surface.
@param context GPU context
@param layer GrMTLHandle (expected to be a CAMetalLayer*)
@param origin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
@param sampleCnt samples per pixel, or 0 to disable full scene anti-aliasing
@param colorType one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
kRGB_888x_SkColorType, kBGRA_8888_SkColorType,
kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@param colorSpace range of colors; may be nullptr
@param surfaceProps LCD striping orientation and setting for device independent
fonts; may be nullptr
@param drawable Pointer to drawable to be filled in when this surface is
instantiated; may not be nullptr
@return created SkSurface, or nullptr
*/
static sk_sp<SkSurface> MakeFromCAMetalLayer(GrContext* context,
GrMTLHandle layer,
GrSurfaceOrigin origin,
int sampleCnt,
SkColorType colorType,
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
GrMTLHandle* drawable);
#endif
/** Returns SkSurface on GPU indicated by context. Allocates memory for
pixels, based on the width, height, and SkColorType in SkImageInfo. budgeted
selects whether allocation for pixels is tracked by context. imageInfo

View File

@ -0,0 +1,62 @@
/*
* 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"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContext.h"
#include "include/gpu/mtl/GrMtlTypes.h"
#if SK_SUPPORT_GPU
#ifdef SK_METAL
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
sk_sp<SkSurface> SkSurface::MakeFromCAMetalLayer(GrContext* context,
GrMTLHandle layer,
GrSurfaceOrigin origin,
int sampleCnt,
SkColorType colorType,
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
GrMTLHandle* drawable) {
// TODO: Apple recommends grabbing the drawable (which we're implicitly doing here)
// for as little time as possible. I'm not sure it matters for our test apps, but
// you can get better throughput by doing any offscreen renders, texture uploads, or
// other non-dependant tasks first before grabbing the drawable.
CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer;
id<CAMetalDrawable> currentDrawable = [metalLayer nextDrawable];
GrMtlTextureInfo fbInfo;
fbInfo.fTexture.retain((__bridge const void*)(currentDrawable.texture));
CGSize size = [metalLayer drawableSize];
sk_sp<SkSurface> surface;
if (sampleCnt <= 1) {
GrBackendRenderTarget backendRT(size.width,
size.height,
sampleCnt,
fbInfo);
surface = SkSurface::MakeFromBackendRenderTarget(context, backendRT, origin, colorType,
colorSpace, surfaceProps);
} else {
GrBackendTexture backendTexture(size.width,
size.height,
GrMipMapped::kNo,
fbInfo);
surface = SkSurface::MakeFromBackendTexture(context, backendTexture, origin, sampleCnt,
colorType, colorSpace, surfaceProps);
}
*drawable = (__bridge_retained GrMTLHandle) currentDrawable;
return surface;
}
#endif
#endif

View File

@ -72,37 +72,16 @@ void MetalWindowContext::destroyContext() {
sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
sk_sp<SkSurface> surface;
if (fContext) {
// TODO: Apple recommends grabbing the drawable (which we're implicitly doing here)
// for as little time as possible. I'm not sure it matters for our test apps, but
// you can get better throughput by doing any offscreen renders, texture uploads, or
// other non-dependant tasks first before grabbing the drawable.
fCurrentDrawable = [fMetalLayer nextDrawable];
GrMtlTextureInfo fbInfo;
fbInfo.fTexture.retain((__bridge const void*)(fCurrentDrawable.texture));
if (fSampleCount == 1) {
GrBackendRenderTarget backendRT(fWidth,
fHeight,
fSampleCount,
fbInfo);
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);
}
GrMTLHandle drawable;
surface = SkSurface::MakeFromCAMetalLayer(fContext.get(), (__bridge GrMTLHandle)fMetalLayer,
kTopLeft_GrSurfaceOrigin, fSampleCount,
kBGRA_8888_SkColorType,
fDisplayParams.fColorSpace,
&fDisplayParams.fSurfaceProps,
&drawable);
// ARC is off in sk_app, so we need to release the CF ref manually
fCurrentDrawable = (id<CAMetalDrawable>)drawable;
CFRelease(drawable);
}
return surface;