Commit 6231ee5e authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Chromium LUCI CQ

Refactor copy layer code

The same code is used in screen rotator and tablet mode controller.
Refactor and make it a library so that we can use it in different places
like unlock.

Bug: None

Change-Id: I6bbb99c4fc77da8a30379fa8fc4b02ad2d6c7369
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2562962
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarSammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832233}
parent 2be010bb
...@@ -1429,6 +1429,8 @@ component("ash") { ...@@ -1429,6 +1429,8 @@ component("ash") {
"tray_action/tray_action.cc", "tray_action/tray_action.cc",
"tray_action/tray_action.h", "tray_action/tray_action.h",
"tray_action/tray_action_observer.h", "tray_action/tray_action_observer.h",
"utility/layer_util.cc",
"utility/layer_util.h",
"utility/screenshot_controller.cc", "utility/screenshot_controller.cc",
"utility/screenshot_controller.h", "utility/screenshot_controller.h",
"utility/transformer_util.cc", "utility/transformer_util.cc",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ash/rotator/screen_rotation_animation.h" #include "ash/rotator/screen_rotation_animation.h"
#include "ash/rotator/screen_rotation_animator_observer.h" #include "ash/rotator/screen_rotation_animator_observer.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/utility/layer_util.h"
#include "ash/utility/transformer_util.h" #include "ash/utility/transformer_util.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
...@@ -21,7 +22,6 @@ ...@@ -21,7 +22,6 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_result.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/class_property.h" #include "ui/base/class_property.h"
#include "ui/compositor/animation_throughput_reporter.h" #include "ui/compositor/animation_throughput_reporter.h"
...@@ -360,23 +360,14 @@ void ScreenRotationAnimator::CreateOldLayerTreeForSlowAnimation() { ...@@ -360,23 +360,14 @@ void ScreenRotationAnimator::CreateOldLayerTreeForSlowAnimation() {
std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree( std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree(
std::unique_ptr<viz::CopyOutputResult> result) { std::unique_ptr<viz::CopyOutputResult> result) {
DCHECK(!result->IsEmpty()); std::unique_ptr<ui::Layer> copy_layer =
DCHECK_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE); CreateLayerFromCopyOutputResult(std::move(result));
auto transfer_resource = viz::TransferableResource::MakeGL(
result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
result->GetTextureResult()->sync_token, result->size(),
false /* is_overlay_candidate */);
std::unique_ptr<viz::SingleReleaseCallback> release_callback =
result->TakeTextureOwnership();
const gfx::Rect rect( const gfx::Rect rect(
GetScreenRotationContainer(root_window_)->layer()->size()); GetScreenRotationContainer(root_window_)->layer()->size());
std::unique_ptr<ui::Layer> copy_layer = std::make_unique<ui::Layer>();
copy_layer->SetBounds(rect); copy_layer->SetBounds(rect);
// TODO(crbug.com/1040279): This is a workaround and should be removed once // TODO(crbug.com/1040279): This is a workaround and should be removed once
// the issue is fixed. // the issue is fixed.
copy_layer->SetFillsBoundsOpaquely(false); copy_layer->SetFillsBoundsOpaquely(false);
copy_layer->SetTransferableResource(transfer_resource,
std::move(release_callback), rect.size());
return std::make_unique<ui::LayerTreeOwner>(std::move(copy_layer)); return std::make_unique<ui::LayerTreeOwner>(std::move(copy_layer));
} }
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/utility/layer_util.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/geometry/size.h"
namespace ash {
namespace {
void CopyCopyOutputResultToLayer(
std::unique_ptr<viz::CopyOutputResult> copy_result,
ui::Layer* target_layer) {
DCHECK(!copy_result->IsEmpty());
DCHECK_EQ(copy_result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
const gfx::Size layer_size = copy_result->size();
viz::TransferableResource transferable_resource =
viz::TransferableResource::MakeGL(
copy_result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
copy_result->GetTextureResult()->sync_token, layer_size,
/*is_overlay_candidate=*/false);
std::unique_ptr<viz::SingleReleaseCallback> release_callback =
copy_result->TakeTextureOwnership();
target_layer->SetTransferableResource(
transferable_resource, std::move(release_callback), layer_size);
}
void CopyToNewLayerOnCopyRequestFinished(
LayerCopyCallback layer_copy_callback,
std::unique_ptr<viz::CopyOutputResult> copy_result) {
if (!copy_result || copy_result->IsEmpty()) {
std::move(layer_copy_callback).Run(nullptr);
return;
}
auto copy_layer = CreateLayerFromCopyOutputResult(std::move(copy_result));
std::move(layer_copy_callback).Run(std::move(copy_layer));
}
} // namespace
std::unique_ptr<ui::Layer> CreateLayerFromCopyOutputResult(
std::unique_ptr<viz::CopyOutputResult> copy_result) {
auto copy_layer = std::make_unique<ui::Layer>();
CopyCopyOutputResultToLayer(std::move(copy_result), copy_layer.get());
return copy_layer;
}
void CopyLayerContentToNewLayer(ui::Layer* layer, LayerCopyCallback callback) {
auto new_callback =
base::BindOnce(&CopyToNewLayerOnCopyRequestFinished, std::move(callback));
auto copy_request = std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
std::move(new_callback));
gfx::Rect bounds(layer->size());
copy_request->set_area(bounds);
copy_request->set_result_selection(bounds);
layer->RequestCopyOfOutput(std::move(copy_request));
}
} // namespace ash
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_UTILITY_LAYER_UTIL_H_
#define ASH_UTILITY_LAYER_UTIL_H_
#include <memory>
#include "base/callback.h"
namespace ui {
class Layer;
}
namespace viz {
class CopyOutputResult;
}
namespace ash {
using LayerCopyCallback =
base::OnceCallback<void(std::unique_ptr<ui::Layer> new_layer)>;
// Creates the new layer using the image in |copy_result|.
std::unique_ptr<ui::Layer> CreateLayerFromCopyOutputResult(
std::unique_ptr<viz::CopyOutputResult> copy_result);
// Creates a new layer that has a copy of the |layer|'s content. This is an
// async API and a new layer will be passed to the |callback| when copy is done.
void CopyLayerContentToNewLayer(ui::Layer* layer, LayerCopyCallback callback);
} // namespace ash
#endif // ASH_UTILITY_LAYER_UTIL_H_
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_delegate.h" #include "ash/shell_delegate.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ash/utility/layer_util.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/tablet_mode/internal_input_devices_event_blocker.h" #include "ash/wm/tablet_mode/internal_input_devices_event_blocker.h"
...@@ -38,9 +39,6 @@ ...@@ -38,9 +39,6 @@
#include "base/time/tick_clock.h" #include "base/time/tick_clock.h"
#include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power/power_manager_client.h"
#include "chromeos/system/devicemode.h" #include "chromeos/system/devicemode.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/accelerators/accelerator.h" #include "ui/base/accelerators/accelerator.h"
...@@ -161,26 +159,6 @@ bool ShouldObserveSequence(ui::LayerAnimationSequence* sequence) { ...@@ -161,26 +159,6 @@ bool ShouldObserveSequence(ui::LayerAnimationSequence* sequence) {
TabletModeController::GetObservedTabletTransitionProperty(); TabletModeController::GetObservedTabletTransitionProperty();
} }
std::unique_ptr<ui::Layer> CreateLayerFromScreenshotResult(
std::unique_ptr<viz::CopyOutputResult> copy_result) {
DCHECK(!copy_result->IsEmpty());
DCHECK_EQ(copy_result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
const gfx::Size layer_size = copy_result->size();
viz::TransferableResource transferable_resource =
viz::TransferableResource::MakeGL(
copy_result->GetTextureResult()->mailbox, GL_LINEAR, GL_TEXTURE_2D,
copy_result->GetTextureResult()->sync_token, layer_size,
/*is_overlay_candidate=*/false);
std::unique_ptr<viz::SingleReleaseCallback> release_callback =
copy_result->TakeTextureOwnership();
auto screenshot_layer = std::make_unique<ui::Layer>();
screenshot_layer->SetTransferableResource(
transferable_resource, std::move(release_callback), layer_size);
return screenshot_layer;
}
// Check if there is any external and internal pointing device in // Check if there is any external and internal pointing device in
// |input_devices|. // |input_devices|.
void CheckHasPointingDevices( void CheckHasPointingDevices(
...@@ -1199,25 +1177,19 @@ void TabletModeController::TakeScreenshot(aura::Window* top_window) { ...@@ -1199,25 +1177,19 @@ void TabletModeController::TakeScreenshot(aura::Window* top_window) {
// Request a screenshot. // Request a screenshot.
screenshot_taken_callback_.Reset(base::BindOnce( screenshot_taken_callback_.Reset(base::BindOnce(
&TabletModeController::OnScreenshotTaken, weak_factory_.GetWeakPtr(), &TabletModeController::OnLayerCopyed, weak_factory_.GetWeakPtr(),
std::move(callback), root_window)); std::move(callback), root_window));
const gfx::Rect request_bounds(screenshot_window->layer()->size()); CopyLayerContentToNewLayer(screenshot_window->layer(),
auto screenshot_request = std::make_unique<viz::CopyOutputRequest>( screenshot_taken_callback_.callback());
viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
screenshot_taken_callback_.callback());
screenshot_request->set_area(request_bounds);
screenshot_request->set_result_selection(request_bounds);
screenshot_window->layer()->RequestCopyOfOutput(
std::move(screenshot_request));
VLOG(1) << "Tablet screenshot requested."; VLOG(1) << "Tablet screenshot requested.";
} }
void TabletModeController::OnScreenshotTaken( void TabletModeController::OnLayerCopyed(
base::OnceClosure on_screenshot_taken, base::OnceClosure on_screenshot_taken,
aura::Window* root_window, aura::Window* root_window,
std::unique_ptr<viz::CopyOutputResult> copy_result) { std::unique_ptr<ui::Layer> copy_layer) {
aura::Window* top_window = aura::Window* top_window =
destroy_observer_ ? destroy_observer_->window() : nullptr; destroy_observer_ ? destroy_observer_->window() : nullptr;
ResetDestroyObserver(); ResetDestroyObserver();
...@@ -1228,14 +1200,14 @@ void TabletModeController::OnScreenshotTaken( ...@@ -1228,14 +1200,14 @@ void TabletModeController::OnScreenshotTaken(
if (!base::Contains(Shell::GetAllRootWindows(), root_window)) if (!base::Contains(Shell::GetAllRootWindows(), root_window))
return; return;
if (!copy_result || copy_result->IsEmpty() || !top_window) { if (!copy_layer || !top_window) {
std::move(on_screenshot_taken).Run(); std::move(on_screenshot_taken).Run();
return; return;
} }
// Stack the screenshot under |top_window|, to fully occlude all windows // Stack the screenshot under |top_window|, to fully occlude all windows
// except |top_window| for the duration of the enter tablet mode animation. // except |top_window| for the duration of the enter tablet mode animation.
screenshot_layer_ = CreateLayerFromScreenshotResult(std::move(copy_result)); screenshot_layer_ = std::move(copy_layer);
top_window->parent()->layer()->Add(screenshot_layer_.get()); top_window->parent()->layer()->Add(screenshot_layer_.get());
screenshot_layer_->SetBounds(top_window->GetRootWindow()->bounds()); screenshot_layer_->SetBounds(top_window->GetRootWindow()->bounds());
top_window->parent()->layer()->StackBelow(screenshot_layer_.get(), top_window->parent()->layer()->StackBelow(screenshot_layer_.get(),
......
...@@ -53,10 +53,6 @@ namespace views { ...@@ -53,10 +53,6 @@ namespace views {
class Widget; class Widget;
} }
namespace viz {
class CopyOutputResult;
}
namespace ash { namespace ash {
class InternalInputDevicesEventBlocker; class InternalInputDevicesEventBlocker;
...@@ -312,9 +308,9 @@ class ASH_EXPORT TabletModeController ...@@ -312,9 +308,9 @@ class ASH_EXPORT TabletModeController
// Called when a screenshot is taken. Creates |screenshot_widget_| which holds // Called when a screenshot is taken. Creates |screenshot_widget_| which holds
// the screenshot results and stacks it under top window. |root_window| // the screenshot results and stacks it under top window. |root_window|
// specifies on which root window the screen shot is taken. // specifies on which root window the screen shot is taken.
void OnScreenshotTaken(base::OnceClosure on_screenshot_taken, void OnLayerCopyed(base::OnceClosure on_screenshot_taken,
aura::Window* root_window, aura::Window* root_window,
std::unique_ptr<viz::CopyOutputResult> copy_result); std::unique_ptr<ui::Layer> copy_layer);
// Calculates whether the device is currently in a physical tablet state, // Calculates whether the device is currently in a physical tablet state,
// using the most recent seen device events such as lid angle changes. // using the most recent seen device events such as lid angle changes.
...@@ -464,7 +460,7 @@ class ASH_EXPORT TabletModeController ...@@ -464,7 +460,7 @@ class ASH_EXPORT TabletModeController
// Tracks and record transition smoothness. // Tracks and record transition smoothness.
base::Optional<ui::ThroughputTracker> transition_tracker_; base::Optional<ui::ThroughputTracker> transition_tracker_;
base::CancelableOnceCallback<void(std::unique_ptr<viz::CopyOutputResult>)> base::CancelableOnceCallback<void(std::unique_ptr<ui::Layer>)>
screenshot_taken_callback_; screenshot_taken_callback_;
base::CancelableOnceClosure screenshot_set_callback_; base::CancelableOnceClosure screenshot_set_callback_;
......
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