-
Notifications
You must be signed in to change notification settings - Fork 6k
[embedder] Add FBO callback that takes frame info #20617
Conversation
56b270b to
5ff79a7
Compare
See EC-1 in flutter.dev/go/double-buffered-window-resize
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionality LGTM (although @chinmaygarde should definitely review as well), but some nits.
shell/gpu/gpu_surface_gl.cc
Outdated
| } | ||
|
|
||
| GLFrameInfo frame_info = {.width = static_cast<uint32_t>(size.width()), | ||
| .height = static_cast<uint32_t>(size.height())}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Labelled aggregate initialization is non-standard until C++20; please don't use it at this point. (Applies throughout the PR.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/gpu/gpu_surface_gl.cc
Outdated
| return true; | ||
| } | ||
|
|
||
| GLFrameInfo frame_info = {.width = static_cast<uint32_t>(size.width()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please declare this closer to where it's used (per style guide).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
|
||
| namespace flutter { | ||
|
|
||
| struct GLFrameInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a declaration comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| FlutterOpenGLTexture* /* texture out */); | ||
| typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */); | ||
|
|
||
| typedef struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a declaration comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/platform/embedder/embedder.h
Outdated
| uint32_t height; | ||
| } FlutterFrameInfo; | ||
|
|
||
| typedef uint32_t (*FBOWithFrameInfoCallBack)(void* /* user data */, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/platform/embedder/embedder.h
Outdated
| BoolCallback make_current; | ||
| BoolCallback clear_current; | ||
| BoolCallback present; | ||
| /// This is an optional callback. Exactly one of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Optional" seems somewhat misleading here; if someone skims quickly they might think this is the same as the other optional callbacks, where it truly is optional. I would just remove this first sentence and start with the "Exactly one of ..." part. (Same below.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| FlutterOpenGLTexture* /* texture out */); | ||
| typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */); | ||
|
|
||
| typedef struct { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
|
||
| size_t GetSoftwareSurfacePresentCount() const; | ||
|
|
||
| std::vector<FlutterFrameInfo> GetGLFBOFrameInfos(); |
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
chinmaygarde
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits but a good foundation.
| engine.reset(); | ||
| } | ||
|
|
||
| TEST_F(EmbedderTest, FrameInfoContainsValidWidthAndHeight) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another test here to verify that engine initialization is aborted if both the old and new callbacks are specified by the embedder.
shell/platform/embedder/embedder.h
Outdated
| BoolCallback make_current; | ||
| BoolCallback clear_current; | ||
| BoolCallback present; | ||
| /// This is an optional callback. Exactly one of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of saying this is optional, can we say "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.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/platform/embedder/embedder.h
Outdated
| uint32_t height; | ||
| } FlutterFrameInfo; | ||
|
|
||
| typedef uint32_t (*FBOWithFrameInfoCallBack)(void* /* user data */, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe prepositions are used in in the embedder API. Also, the uint32_t needing to be an FBO is not really required. How about UIntFrameInfoCallback instead to keep this consistent with the UIntCallback you are upgrading?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| uint32_t width; | ||
| /// The height of the surface that will be backed by the fbo. | ||
| uint32_t height; | ||
| } FlutterFrameInfo; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
shell/platform/embedder/embedder.cc
Outdated
| nullptr; | ||
| // only one of these callbacks must exist. | ||
| if (fbo_callback_exists == fbo_with_frame_info_callback_exists) { | ||
| LOG_EMBEDDER_ERROR(kInternalInconsistency, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOG_EMBEDDER_ERROR is only used right before returning control to the caller. kInternalInconsistency isn't actually going to be returned to the caller here. Just get rid of this line as the result of IsRendererValid is used to generate the error later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
chinmaygarde
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another pass. Almost there.
shell/platform/embedder/embedder.h
Outdated
| } FlutterFrameInfo; | ||
|
|
||
| typedef uint32_t (*UIntFrameInfoCallback)(void* /* user data */, | ||
| FlutterFrameInfo* /* frame info */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const FlutterFrameInfo* since this is not an in-out parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| // SetOpenGLRendererConfig must be called before this. | ||
| FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL); | ||
| renderer_config_.open_gl.fbo_callback = [](void* context) -> uint32_t { | ||
| FlutterFrameInfo tmp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Zero initialize structs for good measure. That makes it resilient to updates to the struct. So, FlutterFrameInfo frame_info = {}; I'd also avoid vars with terse names like tmp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto about the zero initializing structs and ivar names elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to frame_info, and zero initialized it.
| return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer(); | ||
| opengl_renderer_config_.fbo_with_frame_info_callback = | ||
| [](void* context, FlutterFrameInfo* frame_info) -> uint32_t { | ||
| FlutterFrameInfo tmp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear why you prefer this form of copying of the struct instead of just return reinterpret_cast<EmbedderTestContext*>(context)->GLGetFramebuffer(*frame_info). That is more resilient to updates to the frame info struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy-pasta error.
|
This pull request is not suitable for automatic merging in its current state.
|
| double x; | ||
| double y; | ||
| } FlutterPoint; | ||
|
|
There was a problem hiding this comment.
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.
| frame_latch.Wait(); | ||
|
|
||
| ASSERT_EQ(frames_expected, frames_seen); | ||
| ASSERT_EQ(context.GetGLFBOFrameInfos().size(), frames_seen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is racy. context.GetGLFBOFrameInfos() can have 9 entries.
Flutter conflates the size of the frame that is rendered by the framework and the size of the render surface itself. While these are usually the same, this breaks down in cases where the render surface size is being updated constantly.
To this effect, we will be adding a variant of
fbo_callbackthat takes a FrameInfo struct.fbo_callback_with_frame_info. FrameInfo will contain the size of the layer tree that Flutter plans on rendering to the FBO. This lets us create and return an FBO of the requested size along with any additional bookkeeping.See EC-1 in flutter.dev/go/double-buffered-window-resize and flutter/flutter#44136