mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Enable MSAA behind a command line flag for iOS (flutter/engine#33461)
This commit is contained in:
parent
c1fbff0c90
commit
ce9f6b2e43
@ -91,7 +91,7 @@ PointerDataDispatcherMaker ShellTestPlatformViewMetal::GetDispatcherMaker() {
|
||||
|
||||
// |PlatformView|
|
||||
std::unique_ptr<Surface> ShellTestPlatformViewMetal::CreateRenderingSurface() {
|
||||
return std::make_unique<GPUSurfaceMetalSkia>(this, [metal_context_->context() mainContext]);
|
||||
return std::make_unique<GPUSurfaceMetalSkia>(this, [metal_context_->context() mainContext], 1);
|
||||
}
|
||||
|
||||
// |GPUSurfaceMetalDelegate|
|
||||
|
||||
@ -17,6 +17,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface {
|
||||
public:
|
||||
GPUSurfaceMetalSkia(GPUSurfaceMetalDelegate* delegate,
|
||||
sk_sp<GrDirectContext> context,
|
||||
int msaa_samples,
|
||||
bool render_to_surface = true);
|
||||
|
||||
// |Surface|
|
||||
@ -30,6 +31,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface {
|
||||
const MTLRenderTargetType render_target_type_;
|
||||
sk_sp<GrDirectContext> context_;
|
||||
GrDirectContext* precompiled_sksl_context_ = nullptr;
|
||||
int msaa_samples_ = 1;
|
||||
// TODO(38466): Refactor GPU surface APIs take into account the fact that an
|
||||
// external view embedder may want to render to the root surface. This is a
|
||||
// hack to make avoid allocating resources for the root surface when an
|
||||
|
||||
@ -47,11 +47,18 @@ sk_sp<SkSurface> CreateSurfaceFromMetalTexture(GrDirectContext* context,
|
||||
|
||||
GPUSurfaceMetalSkia::GPUSurfaceMetalSkia(GPUSurfaceMetalDelegate* delegate,
|
||||
sk_sp<GrDirectContext> context,
|
||||
int msaa_samples,
|
||||
bool render_to_surface)
|
||||
: delegate_(delegate),
|
||||
render_target_type_(delegate->GetRenderTargetType()),
|
||||
context_(std::move(context)),
|
||||
render_to_surface_(render_to_surface) {}
|
||||
msaa_samples_(msaa_samples),
|
||||
render_to_surface_(render_to_surface) {
|
||||
// Skia allows 0 and clamps it to 1.
|
||||
FML_CHECK(msaa_samples_ == 0 || msaa_samples_ == 1 || msaa_samples_ == 2 || msaa_samples_ == 4 ||
|
||||
msaa_samples_ == 8)
|
||||
<< "Invalid MSAA sample count value: " << msaa_samples_;
|
||||
}
|
||||
|
||||
GPUSurfaceMetalSkia::~GPUSurfaceMetalSkia() = default;
|
||||
|
||||
@ -120,20 +127,9 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalSkia::AcquireFrameFromCAMetalLayer(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(dnfield): Enable MSAA behind a flag if the settings say to.
|
||||
// https://github.com/flutter/flutter/issues/100392
|
||||
// Rough outline of steps needed:
|
||||
// Create memoryless texture
|
||||
// auto texture = drawable.get().texture;
|
||||
// MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:
|
||||
// texture.pixelFormat width: texture.width height: texture.height: mipmapped: texture.mipmapped];
|
||||
// desc.sampleCount = 4;
|
||||
// Type should be multisample, count 4 or 8 (4 always supported)
|
||||
// Give the new texture to skia in this call, using the same sampleCount value
|
||||
// Resolve texture
|
||||
auto surface = CreateSurfaceFromMetalTexture(context_.get(), drawable.get().texture,
|
||||
kTopLeft_GrSurfaceOrigin, // origin
|
||||
1, // sample count
|
||||
msaa_samples_, // sample count
|
||||
kBGRA_8888_SkColorType, // color type
|
||||
nullptr, // colorspace
|
||||
nullptr // surface properties
|
||||
@ -197,8 +193,8 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalSkia::AcquireFrameFromMTLTexture(
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> surface =
|
||||
CreateSurfaceFromMetalTexture(context_.get(), mtl_texture, kTopLeft_GrSurfaceOrigin, 1,
|
||||
kBGRA_8888_SkColorType, nullptr, nullptr);
|
||||
CreateSurfaceFromMetalTexture(context_.get(), mtl_texture, kTopLeft_GrSurfaceOrigin,
|
||||
msaa_samples_, kBGRA_8888_SkColorType, nullptr, nullptr);
|
||||
|
||||
if (!surface) {
|
||||
FML_LOG(ERROR) << "Could not create the SkSurface from the metal texture.";
|
||||
|
||||
@ -19,6 +19,7 @@ namespace flutter {
|
||||
namespace {
|
||||
|
||||
class FakeDelegate : public PlatformView::Delegate {
|
||||
public:
|
||||
void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override {}
|
||||
void OnPlatformViewDestroyed() override {}
|
||||
void OnPlatformViewScheduleFrame() override {}
|
||||
@ -47,7 +48,6 @@ class FakeDelegate : public PlatformView::Delegate {
|
||||
void UpdateAssetResolverByType(std::unique_ptr<AssetResolver> updated_asset_resolver,
|
||||
AssetResolver::AssetResolverType type) override {}
|
||||
|
||||
private:
|
||||
flutter::Settings settings_;
|
||||
};
|
||||
|
||||
@ -87,6 +87,29 @@ flutter::FakeDelegate fake_delegate;
|
||||
return weak_factory->GetWeakPtr();
|
||||
}
|
||||
|
||||
- (void)testMsaaSampleCount {
|
||||
// Default should be 1.
|
||||
XCTAssertEqual(platform_view->GetIosContext()->GetMsaaSampleCount(), 1);
|
||||
|
||||
// Verify the platform view creates a new context with updated msaa_samples.
|
||||
// Need to use Metal, since this is ignored for Software/GL.
|
||||
fake_delegate.settings_.msaa_samples = 4;
|
||||
|
||||
auto thread_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
|
||||
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
|
||||
/*platform=*/thread_task_runner,
|
||||
/*raster=*/thread_task_runner,
|
||||
/*ui=*/thread_task_runner,
|
||||
/*io=*/thread_task_runner);
|
||||
auto msaa_4x_platform_view = std::make_unique<flutter::PlatformViewIOS>(
|
||||
/*delegate=*/fake_delegate,
|
||||
/*rendering_api=*/flutter::IOSRenderingAPI::kMetal,
|
||||
/*platform_views_controller=*/nil,
|
||||
/*task_runners=*/runners);
|
||||
|
||||
XCTAssertEqual(msaa_4x_platform_view->GetIosContext()->GetMsaaSampleCount(), 4);
|
||||
}
|
||||
|
||||
- (void)testCallsNotifyLowMemory {
|
||||
id project = OCMClassMock([FlutterDartProject class]);
|
||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"tester" project:project];
|
||||
|
||||
@ -21,6 +21,9 @@ class Context;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
// Supported MSAA sample count values for iOS.
|
||||
enum class MsaaSampleCount { kNone = 1, kTwo = 2, kFour = 4, kEight = 8 };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Manages the lifetime of the on-screen and off-screen rendering
|
||||
/// contexts on iOS. On-screen contexts are used by Flutter for
|
||||
@ -45,10 +48,17 @@ class IOSContext {
|
||||
///
|
||||
/// @param[in] api A client rendering API supported by the
|
||||
/// engine/platform.
|
||||
/// @param[in] backend A client rendering backend supported by the
|
||||
/// engine/platform.
|
||||
/// @param[in] msaa_samples
|
||||
/// The number of MSAA samples to use. Only supplied to
|
||||
/// Skia, must be either 0, 1, 2, 4, or 8.
|
||||
///
|
||||
/// @return A valid context on success. `nullptr` on failure.
|
||||
///
|
||||
static std::unique_ptr<IOSContext> Create(IOSRenderingAPI api, IOSRenderingBackend backend);
|
||||
static std::unique_ptr<IOSContext> Create(IOSRenderingAPI api,
|
||||
IOSRenderingBackend backend,
|
||||
MsaaSampleCount msaa_samples);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Collects the context object. This must happen on the thread on
|
||||
@ -133,10 +143,13 @@ class IOSContext {
|
||||
|
||||
virtual std::shared_ptr<impeller::Context> GetImpellerContext() const;
|
||||
|
||||
int GetMsaaSampleCount() const { return static_cast<int>(msaa_samples_); }
|
||||
|
||||
protected:
|
||||
IOSContext();
|
||||
explicit IOSContext(MsaaSampleCount msaa_samples);
|
||||
|
||||
private:
|
||||
MsaaSampleCount msaa_samples_ = MsaaSampleCount::kNone;
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(IOSContext);
|
||||
};
|
||||
|
||||
|
||||
@ -15,11 +15,13 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContext::IOSContext() = default;
|
||||
IOSContext::IOSContext(MsaaSampleCount msaa_samples) : msaa_samples_(msaa_samples) {}
|
||||
|
||||
IOSContext::~IOSContext() = default;
|
||||
|
||||
std::unique_ptr<IOSContext> IOSContext::Create(IOSRenderingAPI api, IOSRenderingBackend backend) {
|
||||
std::unique_ptr<IOSContext> IOSContext::Create(IOSRenderingAPI api,
|
||||
IOSRenderingBackend backend,
|
||||
MsaaSampleCount msaa_samples) {
|
||||
switch (api) {
|
||||
case IOSRenderingAPI::kOpenGLES:
|
||||
return std::make_unique<IOSContextGL>();
|
||||
@ -29,7 +31,7 @@ std::unique_ptr<IOSContext> IOSContext::Create(IOSRenderingAPI api, IOSRendering
|
||||
case IOSRenderingAPI::kMetal:
|
||||
switch (backend) {
|
||||
case IOSRenderingBackend::kSkia:
|
||||
return std::make_unique<IOSContextMetalSkia>();
|
||||
return std::make_unique<IOSContextMetalSkia>(msaa_samples);
|
||||
case IOSRenderingBackend::kImpeller:
|
||||
return std::make_unique<IOSContextMetalImpeller>();
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContextGL::IOSContextGL() {
|
||||
IOSContextGL::IOSContextGL() : IOSContext(MsaaSampleCount::kNone) {
|
||||
resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]);
|
||||
if (resource_context_ != nullptr) {
|
||||
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
|
||||
|
||||
@ -22,7 +22,8 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
IOSContextMetalImpeller::IOSContextMetalImpeller() : context_(CreateImpellerContext()) {}
|
||||
IOSContextMetalImpeller::IOSContextMetalImpeller()
|
||||
: IOSContext(MsaaSampleCount::kFour), context_(CreateImpellerContext()) {}
|
||||
|
||||
IOSContextMetalImpeller::~IOSContextMetalImpeller() = default;
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ namespace flutter {
|
||||
|
||||
class IOSContextMetalSkia final : public IOSContext {
|
||||
public:
|
||||
IOSContextMetalSkia();
|
||||
explicit IOSContextMetalSkia(MsaaSampleCount msaa_samples);
|
||||
|
||||
~IOSContextMetalSkia();
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContextMetalSkia::IOSContextMetalSkia() {
|
||||
IOSContextMetalSkia::IOSContextMetalSkia(MsaaSampleCount msaa_samples) : IOSContext(msaa_samples) {
|
||||
darwin_context_metal_ = fml::scoped_nsobject<FlutterDarwinContextMetal>{
|
||||
[[FlutterDarwinContextMetal alloc] initWithDefaultMTLDevice]};
|
||||
|
||||
|
||||
@ -3,10 +3,11 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "flutter/shell/platform/darwin/ios/ios_context_software.h"
|
||||
#include "ios_context.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
IOSContextSoftware::IOSContextSoftware() = default;
|
||||
IOSContextSoftware::IOSContextSoftware() : IOSContext(MsaaSampleCount::kNone) {}
|
||||
|
||||
// |IOSContext|
|
||||
IOSContextSoftware::~IOSContextSoftware() = default;
|
||||
|
||||
@ -42,8 +42,9 @@ void IOSSurfaceMetalSkia::UpdateStorageSizeIfNecessary() {
|
||||
// |IOSSurface|
|
||||
std::unique_ptr<Surface> IOSSurfaceMetalSkia::CreateGPUSurface(GrDirectContext* context) {
|
||||
FML_DCHECK(context);
|
||||
return std::make_unique<GPUSurfaceMetalSkia>(this, // layer
|
||||
sk_ref_sp(context) // context
|
||||
return std::make_unique<GPUSurfaceMetalSkia>(this, // delegate
|
||||
sk_ref_sp(context), // context
|
||||
GetContext()->GetMsaaSampleCount() // sample count
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -55,13 +55,15 @@ PlatformViewIOS::PlatformViewIOS(
|
||||
IOSRenderingAPI rendering_api,
|
||||
const std::shared_ptr<FlutterPlatformViewsController>& platform_views_controller,
|
||||
flutter::TaskRunners task_runners)
|
||||
: PlatformViewIOS(delegate,
|
||||
IOSContext::Create(rendering_api,
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller
|
||||
? IOSRenderingBackend::kImpeller
|
||||
: IOSRenderingBackend::kSkia),
|
||||
platform_views_controller,
|
||||
task_runners) {}
|
||||
: PlatformViewIOS(
|
||||
delegate,
|
||||
IOSContext::Create(
|
||||
rendering_api,
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller ? IOSRenderingBackend::kImpeller
|
||||
: IOSRenderingBackend::kSkia,
|
||||
static_cast<MsaaSampleCount>(delegate.OnPlatformViewGetSettings().msaa_samples)),
|
||||
platform_views_controller,
|
||||
task_runners) {}
|
||||
|
||||
PlatformViewIOS::~PlatformViewIOS() = default;
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ std::unique_ptr<Surface> EmbedderSurfaceMetal::CreateGPUSurface() API_AVAILABLE(
|
||||
}
|
||||
|
||||
const bool render_to_surface = !external_view_embedder_;
|
||||
auto surface = std::make_unique<GPUSurfaceMetalSkia>(this, main_context_, render_to_surface);
|
||||
auto surface = std::make_unique<GPUSurfaceMetalSkia>(this, main_context_, render_to_surface, 1);
|
||||
|
||||
if (!surface->IsValid()) {
|
||||
return nullptr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user