Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Manage resource and onscreen contexts using separate IOSGLContext objects #12277

Merged
merged 3 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@

- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithContentsScale:(CGFloat)contentsScale;
- (std::unique_ptr<flutter::IOSSurface>)createSurface:
(std::shared_ptr<flutter::IOSGLContext>)gl_context;
- (std::unique_ptr<flutter::IOSSurface>)
createSurfaceWithOnscreenGLContext:(fml::WeakPtr<flutter::IOSGLContext>)onscreenGLContext
resourceGLContext:(fml::WeakPtr<flutter::IOSGLContext>)resourceGLContext;

@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,17 @@ + (Class)layerClass {
#endif // TARGET_IPHONE_SIMULATOR
}

- (std::unique_ptr<flutter::IOSSurface>)createSurface:
(std::shared_ptr<flutter::IOSGLContext>)gl_context {
- (std::unique_ptr<flutter::IOSSurface>)
createSurfaceWithOnscreenGLContext:(fml::WeakPtr<flutter::IOSGLContext>)onscreenGLContext
resourceGLContext:(fml::WeakPtr<flutter::IOSGLContext>)resourceGLContext {
if ([self.layer isKindOfClass:[CAEAGLLayer class]]) {
fml::scoped_nsobject<CAEAGLLayer> eagl_layer(
reinterpret_cast<CAEAGLLayer*>([self.layer retain]));
if (@available(iOS 9.0, *)) {
eagl_layer.get().presentsWithTransaction = YES;
}
return std::make_unique<flutter::IOSSurfaceGL>(std::move(eagl_layer), gl_context);
return std::make_unique<flutter::IOSSurfaceGL>(std::move(eagl_layer), onscreenGLContext,
resourceGLContext);
#if FLUTTER_SHELL_ENABLE_METAL
} else if ([self.layer isKindOfClass:[CAMetalLayer class]]) {
fml::scoped_nsobject<CAMetalLayer> metalLayer(
Expand Down
15 changes: 10 additions & 5 deletions shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,13 @@
}

bool FlutterPlatformViewsController::SubmitFrame(GrContext* gr_context,
std::shared_ptr<IOSGLContext> gl_context) {
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context) {
DisposeViews();

bool did_submit = true;
for (int64_t view_id : composition_order_) {
EnsureOverlayInitialized(view_id, std::move(gl_context), gr_context);
EnsureOverlayInitialized(view_id, onscreen_gl_context, resource_gl_context, gr_context);
auto frame = overlays_[view_id]->surface->AcquireFrame(frame_size_);
SkCanvas* canvas = frame->SkiaCanvas();
canvas->drawPicture(picture_recorders_[view_id]->finishRecordingAsPicture());
Expand Down Expand Up @@ -451,7 +452,8 @@

void FlutterPlatformViewsController::EnsureOverlayInitialized(
int64_t overlay_id,
std::shared_ptr<IOSGLContext> gl_context,
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context,
GrContext* gr_context) {
FML_DCHECK(flutter_view_);

Expand All @@ -467,7 +469,9 @@
overlay_view.get().frame = flutter_view_.get().bounds;
overlay_view.get().autoresizingMask =
(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
std::unique_ptr<IOSSurface> ios_surface = [overlay_view.get() createSurface:nil];
std::unique_ptr<IOSSurface> ios_surface = [overlay_view.get()
createSurfaceWithOnscreenGLContext:fml::WeakPtr<flutter::IOSGLContext>()
resourceGLContext:fml::WeakPtr<flutter::IOSGLContext>()];
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface();
overlays_[overlay_id] = std::make_unique<FlutterPlatformViewLayer>(
std::move(overlay_view), std::move(ios_surface), std::move(surface));
Expand All @@ -492,7 +496,8 @@
overlay_view.get().autoresizingMask =
(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
std::unique_ptr<IOSSurface> ios_surface =
[overlay_view.get() createSurface:std::move(gl_context)];
[overlay_view.get() createSurfaceWithOnscreenGLContext:std::move(onscreen_gl_context)
resourceGLContext:std::move(resource_gl_context)];
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface(gr_context);
overlays_[overlay_id] = std::make_unique<FlutterPlatformViewLayer>(
std::move(overlay_view), std::move(ios_surface), std::move(surface));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ class FlutterPlatformViewsController {
// Discards all platform views instances and auxiliary resources.
void Reset();

bool SubmitFrame(GrContext* gr_context, std::shared_ptr<IOSGLContext> gl_context);
bool SubmitFrame(GrContext* gr_context,
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context);

void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);

Expand Down Expand Up @@ -162,7 +164,8 @@ class FlutterPlatformViewsController {
// Dispose the views in `views_to_dispose_`.
void DisposeViews();
void EnsureOverlayInitialized(int64_t overlay_id,
std::shared_ptr<IOSGLContext> gl_context,
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context,
GrContext* gr_context);

// This will return true after pre-roll if any of the embedded views
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterView.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

- (instancetype)initWithDelegate:(id<FlutterViewEngineDelegate>)delegate
opaque:(BOOL)opaque NS_DESIGNATED_INITIALIZER;
- (std::unique_ptr<flutter::IOSSurface>)createSurface:
(std::shared_ptr<flutter::IOSGLContext>)context;
- (std::unique_ptr<flutter::IOSSurface>)createSurfaceWithResourceGLContext:
(fml::WeakPtr<flutter::IOSGLContext>)resourceGLContext;

@end

Expand Down
23 changes: 16 additions & 7 deletions shell/platform/darwin/ios/framework/Source/FlutterView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#include "flutter/shell/platform/darwin/ios/ios_gl_context.h"
#include "flutter/shell/platform/darwin/ios/ios_surface_gl.h"
#include "flutter/shell/platform/darwin/ios/ios_surface_software.h"
#include "third_party/skia/include/utils/mac/SkCGUtils.h"
Expand All @@ -21,9 +22,10 @@
#include "flutter/shell/platform/darwin/ios/ios_surface_metal.h"
#endif // FLUTTER_SHELL_ENABLE_METAL

@implementation FlutterView

id<FlutterViewEngineDelegate> _delegate;
@implementation FlutterView {
id<FlutterViewEngineDelegate> _delegate;
std::unique_ptr<flutter::IOSGLContext> _onscreenGLContext;
}

- (instancetype)init {
@throw([NSException exceptionWithName:@"FlutterView must initWithDelegate"
Expand Down Expand Up @@ -93,8 +95,14 @@ + (Class)layerClass {
#endif // TARGET_IPHONE_SIMULATOR
}

- (std::unique_ptr<flutter::IOSSurface>)createSurface:
(std::shared_ptr<flutter::IOSGLContext>)context {
- (std::unique_ptr<flutter::IOSSurface>)createSurfaceWithResourceGLContext:
(fml::WeakPtr<flutter::IOSGLContext>)resourceGLContext {
#if !TARGET_IPHONE_SIMULATOR
if (!_onscreenGLContext) {
_onscreenGLContext = resourceGLContext->MakeSharedContext();
}
#endif // !TARGET_IPHONE_SIMULATOR

if ([self.layer isKindOfClass:[CAEAGLLayer class]]) {
fml::scoped_nsobject<CAEAGLLayer> eagl_layer(
reinterpret_cast<CAEAGLLayer*>([self.layer retain]));
Expand All @@ -105,8 +113,9 @@ + (Class)layerClass {
eagl_layer.get().presentsWithTransaction = YES;
}
}
return std::make_unique<flutter::IOSSurfaceGL>(context, std::move(eagl_layer),
[_delegate platformViewsController]);
return std::make_unique<flutter::IOSSurfaceGL>(
_onscreenGLContext->GetWeakPtr(), std::move(resourceGLContext), std::move(eagl_layer),
[_delegate platformViewsController]);
#if FLUTTER_SHELL_ENABLE_METAL
} else if ([self.layer isKindOfClass:[CAMetalLayer class]]) {
fml::scoped_nsobject<CAMetalLayer> metalLayer(
Expand Down
14 changes: 8 additions & 6 deletions shell/platform/darwin/ios/ios_gl_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,32 @@
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "ios_gl_render_target.h"

namespace flutter {

class IOSGLContext {
public:
IOSGLContext();
IOSGLContext(EAGLSharegroup* sharegroup);

~IOSGLContext();

std::unique_ptr<IOSGLRenderTarget> CreateRenderTarget(
fml::scoped_nsobject<CAEAGLLayer> layer);

bool MakeCurrent();

bool ResourceMakeCurrent();
bool BindRenderbufferStorage(fml::scoped_nsobject<CAEAGLLayer> layer);

sk_sp<SkColorSpace> ColorSpace() const { return color_space_; }

std::unique_ptr<IOSGLContext> MakeSharedContext();

fml::WeakPtr<IOSGLContext> GetWeakPtr();

private:
fml::scoped_nsobject<EAGLContext> context_;
fml::scoped_nsobject<EAGLContext> resource_context_;
sk_sp<SkColorSpace> color_space_;

std::unique_ptr<fml::WeakPtrFactory<IOSGLContext>> weak_factory_;

FML_DISALLOW_COPY_AND_ASSIGN(IOSGLContext);
};

Expand Down
33 changes: 18 additions & 15 deletions shell/platform/darwin/ios/ios_gl_context.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@

namespace flutter {

IOSGLContext::IOSGLContext() {
resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]);
if (resource_context_ != nullptr) {
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
sharegroup:resource_context_.get().sharegroup]);
} else {
resource_context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]);
IOSGLContext::IOSGLContext() : IOSGLContext(nullptr) {}

IOSGLContext::IOSGLContext(EAGLSharegroup* sharegroup)
: weak_factory_(std::make_unique<fml::WeakPtrFactory<IOSGLContext>>(this)) {
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
sharegroup:sharegroup]);

if (!context_) {
context_.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
sharegroup:resource_context_.get().sharegroup]);
sharegroup:sharegroup]);
}

// TODO:
Expand All @@ -44,20 +45,22 @@
}
}

IOSGLContext::~IOSGLContext() = default;
fml::WeakPtr<IOSGLContext> IOSGLContext::GetWeakPtr() {
return weak_factory_->GetWeakPtr();
}

std::unique_ptr<IOSGLRenderTarget> IOSGLContext::CreateRenderTarget(
fml::scoped_nsobject<CAEAGLLayer> layer) {
return std::make_unique<IOSGLRenderTarget>(std::move(layer), context_.get(),
resource_context_.get());
bool IOSGLContext::BindRenderbufferStorage(fml::scoped_nsobject<CAEAGLLayer> layer) {
return [context_.get() renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer.get()];
}

IOSGLContext::~IOSGLContext() = default;

bool IOSGLContext::MakeCurrent() {
return [EAGLContext setCurrentContext:context_.get()];
}

bool IOSGLContext::ResourceMakeCurrent() {
return [EAGLContext setCurrentContext:resource_context_.get()];
std::unique_ptr<IOSGLContext> IOSGLContext::MakeSharedContext() {
return std::make_unique<IOSGLContext>(context_.get().sharegroup);
}

} // namespace flutter
9 changes: 5 additions & 4 deletions shell/platform/darwin/ios/ios_gl_render_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/darwin/ios/ios_gl_context.h"

namespace flutter {

class IOSGLRenderTarget {
public:
IOSGLRenderTarget(fml::scoped_nsobject<CAEAGLLayer> layer,
EAGLContext* context,
EAGLContext* resource_context);
fml::WeakPtr<IOSGLContext> onscreen_context,
fml::WeakPtr<IOSGLContext> resource_context);

~IOSGLRenderTarget();

Expand All @@ -40,8 +41,8 @@ class IOSGLRenderTarget {

private:
fml::scoped_nsobject<CAEAGLLayer> layer_;
fml::scoped_nsobject<EAGLContext> context_;
fml::scoped_nsobject<EAGLContext> resource_context_;
fml::WeakPtr<IOSGLContext> onscreen_gl_context_;
fml::WeakPtr<IOSGLContext> resource_gl_context_;
GLuint framebuffer_;
GLuint colorbuffer_;
GLint storage_size_width_;
Expand Down
25 changes: 12 additions & 13 deletions shell/platform/darwin/ios/ios_gl_render_target.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace flutter {

IOSGLRenderTarget::IOSGLRenderTarget(fml::scoped_nsobject<CAEAGLLayer> layer,
EAGLContext* context,
EAGLContext* resource_context)
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context)
: layer_(std::move(layer)),
context_([context retain]),
resource_context_([resource_context retain]),
onscreen_gl_context_(std::move(onscreen_gl_context)),
resource_gl_context_(std::move(resource_gl_context)),
framebuffer_(GL_NONE),
colorbuffer_(GL_NONE),
storage_size_width_(0),
storage_size_height_(0),
valid_(false) {
FML_DCHECK(layer_ != nullptr);
FML_DCHECK(context_ != nullptr);
FML_DCHECK(resource_context_ != nullptr);
FML_DCHECK(onscreen_gl_context_);
FML_DCHECK(resource_gl_context_);

bool context_current = [EAGLContext setCurrentContext:context_];
bool context_current = onscreen_gl_context_->MakeCurrent();

FML_DCHECK(context_current);
FML_DCHECK(glGetError() == GL_NO_ERROR);
Expand Down Expand Up @@ -63,7 +62,7 @@

IOSGLRenderTarget::~IOSGLRenderTarget() {
EAGLContext* context = EAGLContext.currentContext;
[EAGLContext setCurrentContext:context_];
onscreen_gl_context_->MakeCurrent();
FML_DCHECK(glGetError() == GL_NO_ERROR);

// Deletes on GL_NONEs are ignored
Expand Down Expand Up @@ -105,7 +104,7 @@

FML_DCHECK(glGetError() == GL_NO_ERROR);

if (![EAGLContext setCurrentContext:context_]) {
if (!onscreen_gl_context_->MakeCurrent()) {
return false;
}

Expand All @@ -116,7 +115,7 @@
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
FML_DCHECK(glGetError() == GL_NO_ERROR);

if (![context_.get() renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer_.get()]) {
if (!onscreen_gl_context_->BindRenderbufferStorage(layer_)) {
return false;
}

Expand All @@ -133,11 +132,11 @@
}

bool IOSGLRenderTarget::MakeCurrent() {
return UpdateStorageSizeIfNecessary() && [EAGLContext setCurrentContext:context_.get()];
return UpdateStorageSizeIfNecessary() && onscreen_gl_context_->MakeCurrent();
}

bool IOSGLRenderTarget::ResourceMakeCurrent() {
return [EAGLContext setCurrentContext:resource_context_.get()];
return resource_gl_context_->MakeCurrent();
}

} // namespace flutter
12 changes: 9 additions & 3 deletions shell/platform/darwin/ios/ios_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ class IOSSurfaceGL final : public IOSSurface,
public GPUSurfaceGLDelegate,
public ExternalViewEmbedder {
public:
IOSSurfaceGL(std::shared_ptr<IOSGLContext> context,
IOSSurfaceGL(fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context,
fml::scoped_nsobject<CAEAGLLayer> layer,
FlutterPlatformViewsController* platform_views_controller);

IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer, std::shared_ptr<IOSGLContext> context);
IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
fml::WeakPtr<IOSGLContext> onscreen_gl_context,
fml::WeakPtr<IOSGLContext> resource_gl_context);

~IOSSurfaceGL() override;

Expand Down Expand Up @@ -79,7 +82,10 @@ class IOSSurfaceGL final : public IOSSurface,
bool SubmitFrame(GrContext* context) override;

private:
std::shared_ptr<IOSGLContext> context_;
fml::WeakPtr<IOSGLContext> onscreen_gl_context_;

fml::WeakPtr<IOSGLContext> resource_gl_context_;

std::unique_ptr<IOSGLRenderTarget> render_target_;

FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceGL);
Expand Down
Loading