123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- // 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 "base/bind.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);
- DCHECK_EQ(copy_result->destination(),
- viz::CopyOutputResult::Destination::kNativeTextures);
- const gpu::MailboxHolder& plane = copy_result->GetTextureResult()->planes[0];
- viz::TransferableResource transferable_resource =
- viz::TransferableResource::MakeGL(plane.mailbox, GL_LINEAR,
- plane.texture_target, plane.sync_token,
- copy_result->size(),
- /*is_overlay_candidate=*/false);
- viz::CopyOutputResult::ReleaseCallbacks release_callbacks =
- copy_result->TakeTextureOwnership();
- // CopyOutputResults carrying RGBA format contain a single texture, there
- // should be only one release callback when a result is not empty:
- DCHECK_EQ(1u, release_callbacks.size());
- viz::ReleaseCallback release_callback = std::move(release_callbacks[0]);
- target_layer->SetTransferableResource(
- transferable_resource, std::move(release_callback), target_layer->size());
- }
- void CopyToNewLayerOnCopyRequestFinished(
- LayerCopyCallback layer_copy_callback,
- const gfx::Size& layer_size,
- std::unique_ptr<viz::CopyOutputResult> copy_result) {
- if (!copy_result || copy_result->IsEmpty()) {
- if (!layer_copy_callback.MaybeValid())
- return;
- std::move(layer_copy_callback).Run(nullptr);
- return;
- }
- auto copy_layer =
- CreateLayerFromCopyOutputResult(std::move(copy_result), layer_size);
- std::move(layer_copy_callback).Run(std::move(copy_layer));
- }
- void CopyToLayerOnCopyRequestFinished(
- GetTargetLayerCallback get_target_layer_callback,
- std::unique_ptr<viz::CopyOutputResult> copy_result) {
- if (get_target_layer_callback.IsCancelled())
- return;
- if (!copy_result || copy_result->IsEmpty())
- return;
- ui::Layer* layer = nullptr;
- std::move(get_target_layer_callback).Run(&layer);
- if (!layer)
- return;
- CopyCopyOutputResultToLayer(std::move(copy_result), layer);
- }
- } // namespace
- std::unique_ptr<ui::Layer> CreateLayerFromCopyOutputResult(
- std::unique_ptr<viz::CopyOutputResult> copy_result,
- const gfx::Size& layer_size) {
- auto copy_layer = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
- copy_layer->SetBounds(gfx::Rect(layer_size));
- 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), layer->size());
- auto copy_request = std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA,
- viz::CopyOutputRequest::ResultDestination::kNativeTextures,
- 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));
- }
- void CopyLayerContentToLayer(ui::Layer* layer,
- GetTargetLayerCallback callback) {
- auto new_callback =
- base::BindOnce(&CopyToLayerOnCopyRequestFinished, std::move(callback));
- auto copy_request = std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA,
- viz::CopyOutputRequest::ResultDestination::kNativeTextures,
- 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
|