diff --git a/BUILD.gn b/BUILD.gn index a36d610bf2..5a53a9480d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2421,7 +2421,7 @@ if (skia_enable_tools) { if (is_mac) { sources += [ "tools/sk_app/mac/MetalWindowContext_mac.mm" ] } else if (is_ios) { - # sources += [ "tools/sk_app/mac/MetalWindowContext_ios.mm" ] + sources += [ "tools/sk_app/ios/MetalWindowContext_ios.mm" ] } } diff --git a/tools/sk_app/MetalWindowContext.mm b/tools/sk_app/MetalWindowContext.mm index 78fbf61f8c..766f4f60b7 100644 --- a/tools/sk_app/MetalWindowContext.mm +++ b/tools/sk_app/MetalWindowContext.mm @@ -42,10 +42,6 @@ void MetalWindowContext::initializeContext() { fSampleCount = fDisplayParams.fMSAASampleCount; fStencilBits = 8; - fMetalLayer = [CAMetalLayer layer]; - fMetalLayer.device = fDevice; - fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - fValid = this->onInitializeContext(); fContext = GrContext::MakeMetal((__bridge void*)fDevice, (__bridge void*)fQueue, diff --git a/tools/sk_app/Window.h b/tools/sk_app/Window.h index 988babdcf2..b46a13bf5e 100644 --- a/tools/sk_app/Window.h +++ b/tools/sk_app/Window.h @@ -55,7 +55,7 @@ public: #ifdef SK_VULKAN kVulkan_BackendType, #endif -#if SK_METAL && defined(SK_BUILD_FOR_MAC) +#ifdef SK_METAL kMetal_BackendType, #endif kRaster_BackendType, diff --git a/tools/sk_app/ios/GLWindowContext_ios.mm b/tools/sk_app/ios/GLWindowContext_ios.mm index 9e52cd8ff3..a21f88b61f 100644 --- a/tools/sk_app/ios/GLWindowContext_ios.mm +++ b/tools/sk_app/ios/GLWindowContext_ios.mm @@ -10,17 +10,17 @@ #include "tools/sk_app/GLWindowContext.h" #include "tools/sk_app/ios/WindowContextFactory_ios.h" -#include -#include +#import +#import using sk_app::DisplayParams; using sk_app::window_context_factory::IOSWindowInfo; using sk_app::GLWindowContext; -@interface RasterView : MainView +@interface GLView : MainView @end -@implementation RasterView +@implementation GLView + (Class) layerClass { return [CAEAGLLayer class]; } @@ -44,7 +44,7 @@ public: private: sk_app::Window_ios* fWindow; UIViewController* fViewController; - RasterView* fRasterView; + GLView* fGLView; EAGLContext* fGLContext; GLuint fFramebuffer; GLuint fRenderbuffer; @@ -64,9 +64,9 @@ GLWindowContext_ios::GLWindowContext_ios(const IOSWindowInfo& info, const Displa } GLWindowContext_ios::~GLWindowContext_ios() { - this->onDestroyContext(); - [fRasterView removeFromSuperview]; - [fRasterView release]; + this->destroyContext(); + [fGLView removeFromSuperview]; + [fGLView release]; } sk_sp GLWindowContext_ios::onInitializeContext() { @@ -74,8 +74,8 @@ sk_sp GLWindowContext_ios::onInitializeContext() { SkASSERT(!fGLContext); CGRect frameRect = [fViewController.view frame]; - fRasterView = [[[RasterView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; - [fViewController.view addSubview:fRasterView]; + fGLView = [[[GLView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; + [fViewController.view addSubview:fGLView]; fGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; @@ -92,7 +92,7 @@ sk_sp GLWindowContext_ios::onInitializeContext() { } // Set up EAGLLayer - CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fRasterView.layer; + CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fGLView.layer; eaglLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO, kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8 }; eaglLayer.opaque = YES; diff --git a/tools/sk_app/ios/MetalWindowContext_ios.mm b/tools/sk_app/ios/MetalWindowContext_ios.mm new file mode 100644 index 0000000000..f05ac20198 --- /dev/null +++ b/tools/sk_app/ios/MetalWindowContext_ios.mm @@ -0,0 +1,115 @@ +/* + * 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 "tools/sk_app/MetalWindowContext.h" +#include "tools/sk_app/ios/WindowContextFactory_ios.h" + +#import +#import + +using sk_app::DisplayParams; +using sk_app::window_context_factory::IOSWindowInfo; +using sk_app::MetalWindowContext; + +@interface MetalView : MainView +@end + +@implementation MetalView ++ (Class) layerClass { + return [CAMetalLayer class]; +} +@end + +namespace { + +class MetalWindowContext_ios : public MetalWindowContext { +public: + MetalWindowContext_ios(const IOSWindowInfo&, const DisplayParams&); + + ~MetalWindowContext_ios() override; + + bool onInitializeContext() override; + void onDestroyContext() override; + + void resize(int w, int h) override; + +private: + sk_app::Window_ios* fWindow; + UIViewController* fViewController; + MetalView* fMetalView; + + typedef MetalWindowContext INHERITED; +}; + +MetalWindowContext_ios::MetalWindowContext_ios(const IOSWindowInfo& info, + const DisplayParams& params) + : INHERITED(params) + , fWindow(info.fWindow) + , fViewController(info.fViewController) { + + // any config code here (particularly for msaa)? + + this->initializeContext(); +} + +MetalWindowContext_ios::~MetalWindowContext_ios() { + this->destroyContext(); + [fMetalView removeFromSuperview]; + [fMetalView release]; +} + +bool MetalWindowContext_ios::onInitializeContext() { + SkASSERT(nil != fWindow); + SkASSERT(nil != fViewController); + + CGRect frameRect = [fViewController.view frame]; + fMetalView = [[[MetalView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; + [fViewController.view addSubview:fMetalView]; + + fMetalLayer = (CAMetalLayer*)fMetalView.layer; + fMetalLayer.device = fDevice; + fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + fMetalLayer.drawableSize = frameRect.size; + fMetalLayer.frame = frameRect; + + // TODO: need solution for iOS + // BOOL useVsync = fDisplayParams.fDisableVsync ? NO : YES; + // fMetalLayer.displaySyncEnabled = useVsync; + fMetalLayer.contentsGravity = kCAGravityTopLeft; + + fWidth = frameRect.size.width; + fHeight = frameRect.size.height; + + return true; +} + +void MetalWindowContext_ios::onDestroyContext() {} + +void MetalWindowContext_ios::resize(int w, int h) { + // TODO: handle rotation + fMetalLayer.drawableSize = fMetalView.frame.size; + fMetalLayer.frame = fMetalView.frame; + fWidth = w; + fHeight = h; +} + +} // anonymous namespace + +namespace sk_app { +namespace window_context_factory { + +std::unique_ptr MakeMetalForIOS(const IOSWindowInfo& info, + const DisplayParams& params) { + std::unique_ptr ctx(new MetalWindowContext_ios(info, params)); + if (!ctx->isValid()) { + return nullptr; + } + return ctx; +} + +} // namespace window_context_factory +} // namespace sk_app diff --git a/tools/sk_app/ios/RasterWindowContext_ios.mm b/tools/sk_app/ios/RasterWindowContext_ios.mm index bddcf9de4f..16a21f4f29 100644 --- a/tools/sk_app/ios/RasterWindowContext_ios.mm +++ b/tools/sk_app/ios/RasterWindowContext_ios.mm @@ -13,18 +13,17 @@ #include "tools/sk_app/GLWindowContext.h" #include "tools/sk_app/ios/WindowContextFactory_ios.h" -#include - -#include +#import +#import using sk_app::DisplayParams; using sk_app::window_context_factory::IOSWindowInfo; using sk_app::GLWindowContext; -@interface GLView : MainView +@interface RasterView : MainView @end -@implementation GLView +@implementation RasterView + (Class) layerClass { return [CAEAGLLayer class]; } @@ -53,7 +52,7 @@ public: private: sk_app::Window_ios* fWindow; UIViewController* fViewController; - GLView* fGLView; + RasterView* fRasterView; EAGLContext* fGLContext; GLuint fFramebuffer; GLuint fRenderbuffer; @@ -75,9 +74,9 @@ RasterWindowContext_ios::RasterWindowContext_ios(const IOSWindowInfo& info, } RasterWindowContext_ios::~RasterWindowContext_ios() { - this->onDestroyContext(); - [fGLView removeFromSuperview]; - [fGLView release]; + this->destroyContext(); + [fRasterView removeFromSuperview]; + [fRasterView release]; } sk_sp RasterWindowContext_ios::onInitializeContext() { @@ -85,8 +84,8 @@ sk_sp RasterWindowContext_ios::onInitializeContext() { SkASSERT(!fGLContext); CGRect frameRect = [fViewController.view frame]; - fGLView = [[[GLView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; - [fViewController.view addSubview:fGLView]; + fRasterView = [[[RasterView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; + [fViewController.view addSubview:fRasterView]; fGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; @@ -103,7 +102,7 @@ sk_sp RasterWindowContext_ios::onInitializeContext() { } // Set up EAGLLayer - CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fGLView.layer; + CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fRasterView.layer; eaglLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO, kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8 }; eaglLayer.opaque = YES; diff --git a/tools/sk_app/ios/WindowContextFactory_ios.h b/tools/sk_app/ios/WindowContextFactory_ios.h index 64df86ffe3..513e23a245 100644 --- a/tools/sk_app/ios/WindowContextFactory_ios.h +++ b/tools/sk_app/ios/WindowContextFactory_ios.h @@ -33,10 +33,7 @@ inline std::unique_ptr MakeVulkanForIOS(const IOSWindowInfo&, con return nullptr; } -inline std::unique_ptr MakeMetalForIOS(const IOSWindowInfo&, const DisplayParams&) { - // No Metal support on iOS yet. - return nullptr; -} +std::unique_ptr MakeMetalForIOS(const IOSWindowInfo&, const DisplayParams&); std::unique_ptr MakeGLForIOS(const IOSWindowInfo&, const DisplayParams&); diff --git a/tools/sk_app/ios/Window_ios.mm b/tools/sk_app/ios/Window_ios.mm index e70d15f357..208c14579d 100644 --- a/tools/sk_app/ios/Window_ios.mm +++ b/tools/sk_app/ios/Window_ios.mm @@ -83,11 +83,11 @@ bool Window_ios::attach(BackendType attachType) { case kRaster_BackendType: fWindowContext = MakeRasterForIOS(info, fRequestedDisplayParams); break; -//#ifdef SK_METAL -// case kMetal_BackendType: -// fWindowContext = MakeMetalForMac(info, fRequestedDisplayParams); -// break; -//#endif +#ifdef SK_METAL + case kMetal_BackendType: + fWindowContext = MakeMetalForIOS(info, fRequestedDisplayParams); + break; +#endif case kNativeGL_BackendType: default: fWindowContext = MakeGLForIOS(info, fRequestedDisplayParams); diff --git a/tools/sk_app/mac/MetalWindowContext_mac.mm b/tools/sk_app/mac/MetalWindowContext_mac.mm index 716fbadab3..765980feee 100644 --- a/tools/sk_app/mac/MetalWindowContext_mac.mm +++ b/tools/sk_app/mac/MetalWindowContext_mac.mm @@ -51,6 +51,10 @@ MetalWindowContext_mac::~MetalWindowContext_mac() { bool MetalWindowContext_mac::onInitializeContext() { SkASSERT(nil != fMainView); + fMetalLayer = [CAMetalLayer layer]; + fMetalLayer.device = fDevice; + fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + NSRect frameRect = [fMainView frame]; fMetalLayer.drawableSize = frameRect.size; fMetalLayer.frame = frameRect; diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index eaf83583df..27c03d2a6a 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -141,7 +141,7 @@ const char* kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = { #ifdef SK_VULKAN "Vulkan", #endif -#if defined(SK_METAL) && defined(SK_BUILD_FOR_MAC) +#ifdef SK_METAL "Metal", #endif "Raster" @@ -163,10 +163,10 @@ static sk_app::Window::BackendType get_backend_type(const char* str) { return sk_app::Window::kANGLE_BackendType; } else #endif -#if defined(SK_METAL) && defined(SK_BUILD_FOR_MAC) - if (0 == strcmp(str, "mtl")) { - return sk_app::Window::kMetal_BackendType; - } else +#ifdef SK_METAL + if (0 == strcmp(str, "mtl")) { + return sk_app::Window::kMetal_BackendType; + } else #endif if (0 == strcmp(str, "gl")) { return sk_app::Window::kNativeGL_BackendType; @@ -1556,7 +1556,7 @@ void Viewer::drawImGui() { ImGui::SameLine(); ImGui::RadioButton("Vulkan", &newBackend, sk_app::Window::kVulkan_BackendType); #endif -#if defined(SK_METAL) && defined(SK_BUILD_FOR_MAC) +#if defined(SK_METAL) ImGui::SameLine(); ImGui::RadioButton("Metal", &newBackend, sk_app::Window::kMetal_BackendType); #endif