Commit ac461c4b authored by Klaus Weidner's avatar Klaus Weidner Committed by Commit Bot

Fix framebufferScaleFactor for immersive-ar

WebXR's immersive-ar mode was ignoring UpdateLayerBounds messages,
and framebufferScaleFactor changes caused a size mismatch and GL error.

Process these messages and resize the transfer buffer appropriately,
and keep this separate from the camera image size which isn't affected
by framebufferScaleFactor.

Change-Id: I43db087cd1a9e5c03f9be6a9e4ca6e0fb61007c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1848369
Commit-Queue: Klaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarPiotr Bialecki <bialpio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704013}
parent a3bd306d
...@@ -129,6 +129,7 @@ void ArCoreGl::Initialize(vr::ArCoreSessionUtils* session_utils, ...@@ -129,6 +129,7 @@ void ArCoreGl::Initialize(vr::ArCoreSessionUtils* session_utils,
DCHECK(!is_initialized_); DCHECK(!is_initialized_);
transfer_size_ = frame_size; transfer_size_ = frame_size;
camera_image_size_ = frame_size;
display_rotation_ = display_rotation; display_rotation_ = display_rotation;
should_update_display_geometry_ = true; should_update_display_geometry_ = true;
...@@ -338,7 +339,7 @@ void ArCoreGl::GetFrameData( ...@@ -338,7 +339,7 @@ void ArCoreGl::GetFrameData(
if (should_update_display_geometry_) { if (should_update_display_geometry_) {
// Set display geometry before calling Update. It's a pending request that // Set display geometry before calling Update. It's a pending request that
// applies to the next frame. // applies to the next frame.
arcore_->SetDisplayGeometry(transfer_size_, display_rotation_); arcore_->SetDisplayGeometry(camera_image_size_, display_rotation_);
// Tell the uvs to recalculate on the next animation frame, by which time // Tell the uvs to recalculate on the next animation frame, by which time
// SetDisplayGeometry will have set the new values in arcore_. // SetDisplayGeometry will have set the new values in arcore_.
...@@ -440,6 +441,18 @@ bool ArCoreGl::IsSubmitFrameExpected(int16_t frame_index) { ...@@ -440,6 +441,18 @@ bool ArCoreGl::IsSubmitFrameExpected(int16_t frame_index) {
return true; return true;
} }
void ArCoreGl::CopyCameraImageToFramebuffer() {
// Draw the current camera texture to the output default framebuffer now, if
// available.
if (!have_camera_image_)
return;
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
ar_image_transport_->CopyCameraImageToFramebuffer(camera_image_size_,
uv_transform_);
have_camera_image_ = false;
}
void ArCoreGl::SubmitFrameMissing(int16_t frame_index, void ArCoreGl::SubmitFrameMissing(int16_t frame_index,
const gpu::SyncToken& sync_token) { const gpu::SyncToken& sync_token) {
DVLOG(2) << __func__; DVLOG(2) << __func__;
...@@ -450,13 +463,7 @@ void ArCoreGl::SubmitFrameMissing(int16_t frame_index, ...@@ -450,13 +463,7 @@ void ArCoreGl::SubmitFrameMissing(int16_t frame_index,
webxr_->RecycleUnusedAnimatingFrame(); webxr_->RecycleUnusedAnimatingFrame();
ar_image_transport_->WaitSyncToken(sync_token); ar_image_transport_->WaitSyncToken(sync_token);
// Draw the current camera texture to the output default framebuffer now. CopyCameraImageToFramebuffer();
if (have_camera_image_) {
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
ar_image_transport_->CopyCameraImageToFramebuffer(transfer_size_,
uv_transform_);
have_camera_image_ = false;
}
// We're done with the camera image for this frame, start the next ARCore // We're done with the camera image for this frame, start the next ARCore
// update if we had deferred it. This will get the next frame's camera image // update if we had deferred it. This will get the next frame's camera image
...@@ -492,13 +499,7 @@ void ArCoreGl::SubmitFrameDrawnIntoTexture(int16_t frame_index, ...@@ -492,13 +499,7 @@ void ArCoreGl::SubmitFrameDrawnIntoTexture(int16_t frame_index,
TRACE_EVENT0("gpu", "ArCore SubmitFrame"); TRACE_EVENT0("gpu", "ArCore SubmitFrame");
// Draw the current camera texture to the output default framebuffer now. CopyCameraImageToFramebuffer();
if (have_camera_image_) {
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
ar_image_transport_->CopyCameraImageToFramebuffer(transfer_size_,
uv_transform_);
have_camera_image_ = false;
}
// We're done with the camera image for this frame, start the next ARCore // We're done with the camera image for this frame, start the next ARCore
// update if we had deferred it. This will get the next frame's camera image // update if we had deferred it. This will get the next frame's camera image
...@@ -519,7 +520,7 @@ void ArCoreGl::OnWebXrTokenSignaled(int16_t frame_index, ...@@ -519,7 +520,7 @@ void ArCoreGl::OnWebXrTokenSignaled(int16_t frame_index,
webxr_->TransitionFrameProcessingToRendering(); webxr_->TransitionFrameProcessingToRendering();
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
ar_image_transport_->CopyDrawnImageToFramebuffer(transfer_size_, ar_image_transport_->CopyDrawnImageToFramebuffer(camera_image_size_,
webxr_transform_); webxr_transform_);
surface_->SwapBuffers(base::DoNothing()); surface_->SwapBuffers(base::DoNothing());
DVLOG(3) << __func__ << ": frame=" << frame_index << " SwapBuffers"; DVLOG(3) << __func__ << ": frame=" << frame_index << " SwapBuffers";
...@@ -539,8 +540,9 @@ void ArCoreGl::UpdateLayerBounds(int16_t frame_index, ...@@ -539,8 +540,9 @@ void ArCoreGl::UpdateLayerBounds(int16_t frame_index,
const gfx::RectF& left_bounds, const gfx::RectF& left_bounds,
const gfx::RectF& right_bounds, const gfx::RectF& right_bounds,
const gfx::Size& source_size) { const gfx::Size& source_size) {
DVLOG(2) << __func__; DVLOG(2) << __func__ << " source_size=" << source_size.ToString();
// Nothing to do
transfer_size_ = source_size;
} }
void ArCoreGl::GetEnvironmentIntegrationProvider( void ArCoreGl::GetEnvironmentIntegrationProvider(
......
...@@ -140,6 +140,7 @@ class ArCoreGl : public mojom::XRFrameDataProvider, ...@@ -140,6 +140,7 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
bool InitializeGl(gfx::AcceleratedWidget drawing_widget); bool InitializeGl(gfx::AcceleratedWidget drawing_widget);
bool IsOnGlThread() const; bool IsOnGlThread() const;
void CopyCameraImageToFramebuffer();
base::OnceClosure session_shutdown_callback_; base::OnceClosure session_shutdown_callback_;
...@@ -172,7 +173,14 @@ class ArCoreGl : public mojom::XRFrameDataProvider, ...@@ -172,7 +173,14 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
std::unique_ptr<vr::WebXrPresentationState> webxr_; std::unique_ptr<vr::WebXrPresentationState> webxr_;
// Default dummy values to ensure consistent behaviour. // Default dummy values to ensure consistent behaviour.
// Transfer size is the size of the WebGL framebuffer, this may be
// smaller than the camera image if framebufferScaleFactor is < 1.0.
gfx::Size transfer_size_ = gfx::Size(0, 0); gfx::Size transfer_size_ = gfx::Size(0, 0);
// The camera image size stays locked to the screen size even if
// framebufferScaleFactor changes.
gfx::Size camera_image_size_ = gfx::Size(0, 0);
display::Display::Rotation display_rotation_ = display::Display::ROTATE_0; display::Display::Rotation display_rotation_ = display::Display::ROTATE_0;
bool should_update_display_geometry_ = true; bool should_update_display_geometry_ = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment