Commit 77191cc4 authored by Albert Chaulk's avatar Albert Chaulk Committed by Commit Bot

Allow exo embedded surfaces to crop

Cropping with a SurfaceDrawQuad is done a little differently than with
a texture quad, it need to be scaled up and positioned in the target
space and then clipped using the clip_rect.

Bug: b/143612326
Test: manually
Change-Id: I38e78fd5ff4c60df2c44f9054136d8b27ac55ddc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1972259Reviewed-by: default avatarAlex Sakhartchouk <alexst@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Commit-Queue: Albert Chaulk <achaulk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726540}
parent 0efc4729
......@@ -157,6 +157,13 @@ void WebContentController::AttachTo(aura::Window* window, int window_id) {
// Unretained is safe because we unset this in the destructor.
surface_->SetEmbeddedSurfaceId(
base::Bind(&WebContentController::GetSurfaceId, base::Unretained(this)));
current_rfh_ = GetWebContents()->GetMainFrame();
if (current_rfh_) {
auto size = current_rfh_->GetFrameSize();
if (size.has_value())
surface_->SetEmbeddedSurfaceSize(*size);
}
}
void WebContentController::ProcessInputEvent(const webview::InputEvent& ev) {
......@@ -399,6 +406,13 @@ void WebContentController::OnSurfaceDestroying(exo::Surface* surface) {
surface_ = nullptr;
}
void WebContentController::FrameSizeChanged(
content::RenderFrameHost* render_frame_host,
const gfx::Size& frame_size) {
if (render_frame_host == current_rfh_ && surface_)
surface_->SetEmbeddedSurfaceSize(frame_size);
}
void WebContentController::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
current_render_frame_set_.insert(render_frame_host);
......@@ -414,6 +428,8 @@ void WebContentController::RenderFrameCreated(
void WebContentController::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
current_render_frame_set_.erase(render_frame_host);
if (render_frame_host == current_rfh_)
current_rfh_ = nullptr;
}
void WebContentController::RenderFrameHostChanged(
......@@ -421,8 +437,15 @@ void WebContentController::RenderFrameHostChanged(
content::RenderFrameHost* new_host) {
// The surface ID may have changed, so trigger a new commit to re-issue the
// draw quad.
if (surface_)
current_rfh_ = new_host;
if (surface_) {
if (new_host) {
auto size = new_host->GetFrameSize();
if (size.has_value())
surface_->SetEmbeddedSurfaceSize(*size);
}
surface_->Commit();
}
}
void WebContentController::OnJsClientInstanceRegistered(
......
......@@ -91,6 +91,8 @@ class WebContentController : public exo::SurfaceObserver,
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void RenderFrameHostChanged(content::RenderFrameHost* old_host,
content::RenderFrameHost* new_host) override;
void FrameSizeChanged(content::RenderFrameHost* render_frame_host,
const gfx::Size& frame_size) override;
// JsClientInstance::Observer
void OnJsClientInstanceRegistered(int process_id,
......@@ -100,6 +102,7 @@ class WebContentController : public exo::SurfaceObserver,
ui::GestureRecognizerImpl gesture_recognizer_;
exo::Surface* surface_ = nullptr;
content::RenderFrameHost* current_rfh_ = nullptr;
std::set<std::string> current_javascript_channel_set_;
std::set<content::RenderFrameHost*> current_render_frame_set_;
......
......@@ -561,6 +561,10 @@ void Surface::SetEmbeddedSurfaceId(
first_embedded_surface_id_ = viz::SurfaceId();
}
void Surface::SetEmbeddedSurfaceSize(const gfx::Size& size) {
embedded_surface_size_ = gfx::SizeF(size);
}
void Surface::SetAcquireFence(std::unique_ptr<gfx::GpuFence> gpu_fence) {
TRACE_EVENT1("exo", "Surface::SetAcquireFence", "fence_fd",
gpu_fence ? gpu_fence->GetGpuFenceHandle().native_fd.fd : -1);
......@@ -996,14 +1000,41 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
gfx::ConvertRectToPixel(device_scale_factor, damage_rect));
}
gfx::PointF scale(content_size_.width(), content_size_.height());
gfx::Vector2dF translate(0.0f, 0.0f);
// Surface quads require the quad rect to be appropriately sized and need to
// use the shared quad clip rect.
if (get_current_surface_id_) {
quad_rect = gfx::Rect(content_size_);
// Scale the |embedded_surface_size_| to |content_size_|.
if (embedded_surface_size_.width() || embedded_surface_size_.height()) {
scale.Scale(1.0f / embedded_surface_size_.width(),
1.0f / embedded_surface_size_.height());
}
if (!state_.crop.IsEmpty()) {
// In order to crop an AxB rect to CxD we need to scale by A/C, B/D.
// We achieve clipping by scaling it up and then drawing only in the
// output rectangle.
scale.Scale(content_size_.width() / state_.crop.width(),
content_size_.height() / state_.crop.height());
translate = -state_.crop.origin().OffsetFromOrigin();
}
} else {
scale.Scale(state_.buffer_scale);
}
// Compute the total transformation from post-transform buffer coordinates to
// target coordinates.
SkMatrix viewport_to_target_matrix;
// Scale and offset the normalized space to fit the content size rectangle.
viewport_to_target_matrix.setScale(
content_size_.width() * state_.buffer_scale,
content_size_.height() * state_.buffer_scale);
viewport_to_target_matrix.postTranslate(origin.x(), origin.y());
viewport_to_target_matrix.setScale(scale.x(), scale.y());
gfx::PointF target = gfx::PointF(origin) + translate;
viewport_to_target_matrix.postTranslate(target.x(), target.y());
// Convert from DPs to pixels.
viewport_to_target_matrix.postScale(device_scale_factor, device_scale_factor);
......@@ -1057,13 +1088,17 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
}
}
if (latest_embedded_surface_id_.is_valid()) {
if (!state_.crop.IsEmpty()) {
quad_state->is_clipped = true;
quad_state->clip_rect = output_rect;
}
viz::SurfaceDrawQuad* surface_quad =
render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
surface_quad->SetNew(quad_state, quad_rect, quad_rect,
viz::SurfaceRange(first_embedded_surface_id_,
latest_embedded_surface_id_),
background_color,
/*stretch_content_to_fill_bounds=*/true);
/*stretch_content_to_fill_bounds=*/false);
}
// A resource was still produced for this so we still need to release it
// later.
......
......@@ -180,6 +180,9 @@ class Surface final : public ui::PropertyHandler {
void SetEmbeddedSurfaceId(
base::RepeatingCallback<viz::SurfaceId()> surface_id_callback);
// Set the size of the embedded surface, to allow proper scaling.
void SetEmbeddedSurfaceSize(const gfx::Size& size);
// Request that the attached surface buffer at the next commit is associated
// with a gpu fence to be signaled when the buffer is ready for use.
void SetAcquireFence(std::unique_ptr<gfx::GpuFence> gpu_fence);
......@@ -458,6 +461,10 @@ class Surface final : public ui::PropertyHandler {
viz::SurfaceId latest_embedded_surface_id_;
base::RepeatingCallback<viz::SurfaceId()> get_current_surface_id_;
// The embedded surface is actually |embedded_surface_size_|. This is used
// for calculating clipping and scaling.
gfx::SizeF embedded_surface_size_;
DISALLOW_COPY_AND_ASSIGN(Surface);
};
......
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