| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/shell/common/shell_test_platform_view_metal.h" | |
| #import <Metal/Metal.h> | |
| #include <utility> | |
| #include "flutter/fml/platform/darwin/scoped_nsobject.h" | |
| #include "flutter/shell/gpu/gpu_surface_metal_skia.h" | |
| #include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" | |
| namespace flutter { | |
| namespace testing { | |
| static fml::scoped_nsprotocol<id<MTLTexture>> CreateOffscreenTexture(id<MTLDevice> device) { | |
| auto descriptor = | |
| [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm | |
| width:800 | |
| height:600 | |
| mipmapped:NO]; | |
| descriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; | |
| return fml::scoped_nsprotocol<id<MTLTexture>>{[device newTextureWithDescriptor:descriptor]}; | |
| } | |
| // This is out of the header so that shell_test_platform_view_metal.h can be included in | |
| // non-Objective-C TUs. | |
| class DarwinContextMetal { | |
| public: | |
| DarwinContextMetal() | |
| : context_([[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]), | |
| offscreen_texture_(CreateOffscreenTexture([context_.get() device])) {} | |
| ~DarwinContextMetal() = default; | |
| fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context() const { return context_; } | |
| fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture() const { return offscreen_texture_; } | |
| GPUMTLTextureInfo offscreen_texture_info() const { | |
| GPUMTLTextureInfo info = {}; | |
| info.texture_id = 0; | |
| info.texture = reinterpret_cast<GPUMTLTextureHandle>(offscreen_texture_.get()); | |
| return info; | |
| } | |
| private: | |
| const fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context_; | |
| const fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture_; | |
| FML_DISALLOW_COPY_AND_ASSIGN(DarwinContextMetal); | |
| }; | |
| ShellTestPlatformViewMetal::ShellTestPlatformViewMetal( | |
| PlatformView::Delegate& delegate, | |
| const TaskRunners& task_runners, | |
| std::shared_ptr<ShellTestVsyncClock> vsync_clock, | |
| CreateVsyncWaiter create_vsync_waiter, | |
| std::shared_ptr<ShellTestExternalViewEmbedder> shell_test_external_view_embedder) | |
| : ShellTestPlatformView(delegate, task_runners), | |
| GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), | |
| metal_context_(std::make_unique<DarwinContextMetal>()), | |
| create_vsync_waiter_(std::move(create_vsync_waiter)), | |
| vsync_clock_(std::move(vsync_clock)), | |
| shell_test_external_view_embedder_(std::move(shell_test_external_view_embedder)) { | |
| FML_CHECK([metal_context_->context() mainContext] != nil); | |
| } | |
| ShellTestPlatformViewMetal::~ShellTestPlatformViewMetal() = default; | |
| std::unique_ptr<VsyncWaiter> ShellTestPlatformViewMetal::CreateVSyncWaiter() { | |
| return create_vsync_waiter_(); | |
| } | |
| // |ShellTestPlatformView| | |
| void ShellTestPlatformViewMetal::SimulateVSync() { | |
| vsync_clock_->SimulateVSync(); | |
| } | |
| // |PlatformView| | |
| std::shared_ptr<ExternalViewEmbedder> ShellTestPlatformViewMetal::CreateExternalViewEmbedder() { | |
| return shell_test_external_view_embedder_; | |
| } | |
| // |PlatformView| | |
| PointerDataDispatcherMaker ShellTestPlatformViewMetal::GetDispatcherMaker() { | |
| return [](DefaultPointerDataDispatcher::Delegate& delegate) { | |
| return std::make_unique<SmoothPointerDataDispatcher>(delegate); | |
| }; | |
| } | |
| // |PlatformView| | |
| std::unique_ptr<Surface> ShellTestPlatformViewMetal::CreateRenderingSurface() { | |
| return std::make_unique<GPUSurfaceMetalSkia>(this, [metal_context_->context() mainContext], | |
| MsaaSampleCount::kNone); | |
| } | |
| // |GPUSurfaceMetalDelegate| | |
| GPUCAMetalLayerHandle ShellTestPlatformViewMetal::GetCAMetalLayer(const SkISize& frame_info) const { | |
| FML_CHECK(false) << "A Metal Delegate configured with MTLRenderTargetType::kMTLTexture was asked " | |
| "to acquire a layer."; | |
| return nullptr; | |
| } | |
| // |GPUSurfaceMetalDelegate| | |
| bool ShellTestPlatformViewMetal::PresentDrawable(GrMTLHandle drawable) const { | |
| FML_CHECK(false) << "A Metal Delegate configured with MTLRenderTargetType::kMTLTexture was asked " | |
| "to present a layer drawable."; | |
| return true; | |
| } | |
| // |GPUSurfaceMetalDelegate| | |
| GPUMTLTextureInfo ShellTestPlatformViewMetal::GetMTLTexture(const SkISize& frame_info) const { | |
| return metal_context_->offscreen_texture_info(); | |
| } | |
| // |GPUSurfaceMetalDelegate| | |
| bool ShellTestPlatformViewMetal::PresentTexture(GPUMTLTextureInfo texture) const { | |
| // The texture resides offscreen. There is nothing to render to. | |
| return true; | |
| } | |
| } // namespace testing | |
| } // namespace flutter |