Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
2 changes: 1 addition & 1 deletion shell/common/shell_test_platform_view_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ bool ShellTestPlatformViewGL::GLContextPresent() {
}

// |GPUSurfaceGLDelegate|
intptr_t ShellTestPlatformViewGL::GLContextFBO() const {
intptr_t ShellTestPlatformViewGL::GLContextFBO(GLFrameInfo frame_info) const {
return gl_surface_.GetFramebuffer();
}

Expand Down
2 changes: 1 addition & 1 deletion shell/common/shell_test_platform_view_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView,
bool GLContextPresent() override;

// |GPUSurfaceGLDelegate|
intptr_t GLContextFBO() const override;
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;

// |GPUSurfaceGLDelegate|
GLProcResolver GetGLProcResolver() const override;
Expand Down
21 changes: 13 additions & 8 deletions shell/gpu/gpu_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,12 @@ bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size) {

sk_sp<SkSurface> onscreen_surface;

GLFrameInfo frame_info = {static_cast<uint32_t>(size.width()),
static_cast<uint32_t>(size.height())};
onscreen_surface =
WrapOnscreenSurface(context_.get(), // GL context
size, // root surface size
delegate_->GLContextFBO() // window FBO ID
WrapOnscreenSurface(context_.get(), // GL context
size, // root surface size
delegate_->GLContextFBO(frame_info) // window FBO ID
);

if (onscreen_surface == nullptr) {
Expand Down Expand Up @@ -287,13 +289,16 @@ bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) {
auto current_size =
SkISize::Make(onscreen_surface_->width(), onscreen_surface_->height());

GLFrameInfo frame_info = {static_cast<uint32_t>(current_size.width()),
static_cast<uint32_t>(current_size.height())};

// The FBO has changed, ask the delegate for the new FBO and do a surface
// re-wrap.
auto new_onscreen_surface =
WrapOnscreenSurface(context_.get(), // GL context
current_size, // root surface size
delegate_->GLContextFBO() // window FBO ID
);
auto new_onscreen_surface = WrapOnscreenSurface(
context_.get(), // GL context
current_size, // root surface size
delegate_->GLContextFBO(frame_info) // window FBO ID
);

if (!new_onscreen_surface) {
return false;
Expand Down
13 changes: 10 additions & 3 deletions shell/gpu/gpu_surface_gl_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

namespace flutter {

// A structure to represent the frame information which is passed to the
// embedder when requesting a frame buffer object.
struct GLFrameInfo {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a declaration comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

uint32_t width;
uint32_t height;
};

class GPUSurfaceGLDelegate : public GPUSurfaceDelegate {
public:
~GPUSurfaceGLDelegate() override;
Expand All @@ -33,13 +40,13 @@ class GPUSurfaceGLDelegate : public GPUSurfaceDelegate {
virtual bool GLContextPresent() = 0;

// The ID of the main window bound framebuffer. Typically FBO0.
virtual intptr_t GLContextFBO() const = 0;
virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0;

// The rendering subsystem assumes that the ID of the main window bound
// framebuffer remains constant throughout. If this assumption in incorrect,
// embedders are required to return true from this method. In such cases,
// GLContextFBO() will be called again to acquire the new FBO ID for rendering
// subsequent frames.
// GLContextFBO(frame_info) will be called again to acquire the new FBO ID for
// rendering subsequent frames.
virtual bool GLContextFBOResetAfterPresent() const;

// Indicates whether or not the surface supports pixel readback as used in
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/android_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ bool AndroidSurfaceGL::GLContextPresent() {
return onscreen_surface_->SwapBuffers();
}

intptr_t AndroidSurfaceGL::GLContextFBO() const {
intptr_t AndroidSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
FML_DCHECK(IsValid());
// The default window bound framebuffer on Android.
return 0;
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/android_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
bool GLContextPresent() override;

// |GPUSurfaceGLDelegate|
intptr_t GLContextFBO() const override;
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;

// |GPUSurfaceGLDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/surface/android_surface_mock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ bool AndroidSurfaceMock::GLContextPresent() {
return true;
}

intptr_t AndroidSurfaceMock::GLContextFBO() const {
intptr_t AndroidSurfaceMock::GLContextFBO(GLFrameInfo frame_info) const {
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/surface/android_surface_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AndroidSurfaceMock final : public GPUSurfaceGLDelegate,
bool GLContextPresent() override;

// |GPUSurfaceGLDelegate|
intptr_t GLContextFBO() const override;
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;

// |GPUSurfaceGLDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/darwin/ios/ios_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class IOSSurfaceGL final : public IOSSurface, public GPUSurfaceGLDelegate {
bool GLContextPresent() override;

// |GPUSurfaceGLDelegate|
intptr_t GLContextFBO() const override;
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;

// |GPUSurfaceGLDelegate|
bool SurfaceSupportsReadback() const override;
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/darwin/ios/ios_surface_gl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
}

// |GPUSurfaceGLDelegate|
intptr_t IOSSurfaceGL::GLContextFBO() const {
intptr_t IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
return IsValid() ? render_target_->GetFramebuffer() : GL_NONE;
}

Expand Down
29 changes: 25 additions & 4 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig* config) {

if (SAFE_ACCESS(open_gl_config, make_current, nullptr) == nullptr ||
SAFE_ACCESS(open_gl_config, clear_current, nullptr) == nullptr ||
SAFE_ACCESS(open_gl_config, present, nullptr) == nullptr ||
SAFE_ACCESS(open_gl_config, fbo_callback, nullptr) == nullptr) {
SAFE_ACCESS(open_gl_config, present, nullptr) == nullptr) {
return false;
}

bool fbo_callback_exists =
SAFE_ACCESS(open_gl_config, fbo_callback, nullptr) != nullptr;
bool fbo_with_frame_info_callback_exists =
SAFE_ACCESS(open_gl_config, fbo_with_frame_info_callback, nullptr) !=
nullptr;
// only one of these callbacks must exist.
if (fbo_callback_exists == fbo_with_frame_info_callback_exists) {
return false;
}

Expand Down Expand Up @@ -168,8 +177,20 @@ InferOpenGLPlatformViewCreationCallback(
return ptr(user_data);
};

auto gl_fbo_callback = [ptr = config->open_gl.fbo_callback,
user_data]() -> intptr_t { return ptr(user_data); };
auto gl_fbo_callback =
[fbo_callback = config->open_gl.fbo_callback,
fbo_with_frame_info_callback =
config->open_gl.fbo_with_frame_info_callback,
user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
if (fbo_callback) {
return fbo_callback(user_data);
} else {
FlutterFrameInfo frame_info = {};
frame_info.struct_size = sizeof(FlutterFrameInfo);
frame_info.size = {gl_frame_info.width, gl_frame_info.height};
return fbo_with_frame_info_callback(user_data, &frame_info);
}
};

const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
std::function<bool()> gl_make_resource_current_callback = nullptr;
Expand Down
47 changes: 42 additions & 5 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,46 @@ typedef bool (*TextureFrameCallback)(void* /* user data */,
FlutterOpenGLTexture* /* texture out */);
typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */);

/// A structure to represent the width and height.
typedef struct {
double width;
double height;
} FlutterSize;

/// A structure to represent the width and height.
///
/// See: \ref FlutterSize when the value are not integers.
typedef struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a declaration comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct should start with a size in case we want to add more information to it in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

uint32_t width;
uint32_t height;
} FlutterUIntSize;

/// This information is passed to the embedder when requesting a frame buffer
/// object.
///
/// See: \ref FlutterSoftwareRendererConfig.fbo_with_frame_info_callback.
typedef struct {
/// The size of this struct. Must be sizeof(FlutterFrameInfo).
size_t struct_size;
/// The size of the surface that will be backed by the fbo.
FlutterUIntSize size;
} FlutterFrameInfo;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like something we can reuse later. How about FlutterUIntSize? There is already a FlutterSize but those are doubles.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you foresee a case where this object will be need to expanded? If so, FBOWithFrameInfoCallBack will need to take a pointer to this. It will also need to have a struct size member.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


typedef uint32_t (*UIntFrameInfoCallback)(
void* /* user data */,
const FlutterFrameInfo* /* frame info */);

typedef struct {
/// The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig).
size_t struct_size;
BoolCallback make_current;
BoolCallback clear_current;
BoolCallback present;
/// Specifying one (and only one) of the `fbo_callback` or
/// `fbo_with_frame_info_callback` is required. Specifying both is an error
/// and engine intialization will be terminated. The return value indicates
/// the id of the frame buffer object that flutter will obtain the gl surface
/// from.
UIntCallback fbo_callback;
/// This is an optional callback. Flutter will ask the emebdder to create a GL
/// context current on a background thread. If the embedder is able to do so,
Expand Down Expand Up @@ -342,6 +376,14 @@ typedef struct {
/// that external texture details can be supplied to the engine for subsequent
/// composition.
TextureFrameCallback gl_external_texture_frame_callback;
/// Specifying one (and only one) of the `fbo_callback` or
/// `fbo_with_frame_info_callback` is required. Specifying both is an error
/// and engine intialization will be terminated. The return value indicates
/// the id of the frame buffer object (fbo) that flutter will obtain the gl
/// surface from. When using this variant, the embedder is passed a
/// `FlutterFrameInfo` struct that indicates the properties of the surface
/// that flutter will acquire from the returned fbo.
UIntFrameInfoCallback fbo_with_frame_info_callback;
} FlutterOpenGLRendererConfig;

typedef struct {
Expand Down Expand Up @@ -502,11 +544,6 @@ typedef struct {
double y;
} FlutterPoint;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: maybe move FlutterRect, FlutterPoint, and FLutterRoundedRect up as well so these similar structs all remain together.

typedef struct {
double width;
double height;
} FlutterSize;

typedef struct {
FlutterRect rect;
FlutterSize upper_left_corner_radius;
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/embedder/embedder_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ bool EmbedderSurfaceGL::GLContextPresent() {
}

// |GPUSurfaceGLDelegate|
intptr_t EmbedderSurfaceGL::GLContextFBO() const {
return gl_dispatch_table_.gl_fbo_callback();
intptr_t EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
return gl_dispatch_table_.gl_fbo_callback(frame_info);
}

// |GPUSurfaceGLDelegate|
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/embedder/embedder_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
std::function<bool(void)> gl_make_current_callback; // required
std::function<bool(void)> gl_clear_current_callback; // required
std::function<bool(void)> gl_present_callback; // required
std::function<intptr_t(void)> gl_fbo_callback; // required
std::function<intptr_t(GLFrameInfo)> gl_fbo_callback; // required
std::function<bool(void)> gl_make_resource_current_callback; // optional
std::function<SkMatrix(void)>
gl_surface_transformation_callback; // optional
Expand Down Expand Up @@ -59,7 +59,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
bool GLContextPresent() override;

// |GPUSurfaceGLDelegate|
intptr_t GLContextFBO() const override;
intptr_t GLContextFBO(GLFrameInfo frame_info) const override;

// |GPUSurfaceGLDelegate|
bool GLContextFBOResetAfterPresent() const override;
Expand Down
21 changes: 19 additions & 2 deletions shell/platform/embedder/tests/embedder_config_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ EmbedderConfigBuilder::EmbedderConfigBuilder(
opengl_renderer_config_.present = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContext*>(context)->GLPresent();
};
opengl_renderer_config_.fbo_callback = [](void* context) -> uint32_t {
return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer();
opengl_renderer_config_.fbo_with_frame_info_callback =
[](void* context, const FlutterFrameInfo* frame_info) -> uint32_t {
return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer(
*frame_info);
};
opengl_renderer_config_.make_resource_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContext*>(context)
Expand Down Expand Up @@ -110,6 +112,21 @@ void EmbedderConfigBuilder::SetSoftwareRendererConfig(SkISize surface_size) {
context_.SetupOpenGLSurface(surface_size);
}

void EmbedderConfigBuilder::SetOpenGLFBOCallBack() {
// SetOpenGLRendererConfig must be called before this.
FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
renderer_config_.open_gl.fbo_callback = [](void* context) -> uint32_t {
FlutterFrameInfo frame_info = {};
// fbo_callback doesn't use the frame size information, only
// fbo_callback_with_frame_info does.
frame_info.struct_size = sizeof(FlutterFrameInfo);
frame_info.size.width = 0;
frame_info.size.height = 0;
return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer(
frame_info);
};
}

void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) {
renderer_config_.type = FlutterRendererType::kOpenGL;
renderer_config_.open_gl = opengl_renderer_config_;
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/embedder/tests/embedder_config_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ class EmbedderConfigBuilder {

void SetOpenGLRendererConfig(SkISize surface_size);

// Used to explicitly set an `open_gl.fbo_callback`. Using this method will
// cause your test to fail since the ctor for this class sets
// `open_gl.fbo_callback_with_frame_info`. This method exists as a utility to
// explicitly test this behavior.
void SetOpenGLFBOCallBack();

void SetAssetsPath();

void SetSnapshots();
Expand Down
7 changes: 6 additions & 1 deletion shell/platform/embedder/tests/embedder_test_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,16 @@ bool EmbedderTestContext::GLPresent() {
return true;
}

uint32_t EmbedderTestContext::GLGetFramebuffer() {
uint32_t EmbedderTestContext::GLGetFramebuffer(FlutterFrameInfo frame_info) {
FML_CHECK(gl_surface_) << "GL surface must be initialized.";
gl_surface_fbo_frame_infos_.push_back(frame_info);
return gl_surface_->GetFramebuffer();
}

std::vector<FlutterFrameInfo> EmbedderTestContext::GetGLFBOFrameInfos() {
return gl_surface_fbo_frame_infos_;
}

bool EmbedderTestContext::GLMakeResourceCurrent() {
FML_CHECK(gl_surface_) << "GL surface must be initialized.";
return gl_surface_->MakeResourceCurrent();
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/embedder/tests/embedder_test_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class EmbedderTestContext {

size_t GetSoftwareSurfacePresentCount() const;

// Returns the frame information for all the frames that were rendered.
std::vector<FlutterFrameInfo> GetGLFBOFrameInfos();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a declaration comment, since the implementation isn't inline to make it obvious what it does. (Or, alternately, comment the ivar.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


private:
// This allows the builder to access the hooks.
friend class EmbedderConfigBuilder;
Expand All @@ -101,6 +104,7 @@ class EmbedderTestContext {
std::unique_ptr<EmbedderTestCompositor> compositor_;
NextSceneCallback next_scene_callback_;
SkMatrix root_surface_transformation_;
std::vector<FlutterFrameInfo> gl_surface_fbo_frame_infos_;
size_t gl_surface_present_count_ = 0;
size_t software_surface_present_count_ = 0;

Expand Down Expand Up @@ -133,7 +137,7 @@ class EmbedderTestContext {

bool GLPresent();

uint32_t GLGetFramebuffer();
uint32_t GLGetFramebuffer(FlutterFrameInfo frame_info);

bool GLMakeResourceCurrent();

Expand Down
Loading