layer_util.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/utility/layer_util.h"
  5. #include "base/bind.h"
  6. #include "components/viz/common/frame_sinks/copy_output_request.h"
  7. #include "components/viz/common/frame_sinks/copy_output_result.h"
  8. #include "third_party/khronos/GLES2/gl2.h"
  9. #include "ui/compositor/layer.h"
  10. #include "ui/gfx/geometry/size.h"
  11. namespace ash {
  12. namespace {
  13. void CopyCopyOutputResultToLayer(
  14. std::unique_ptr<viz::CopyOutputResult> copy_result,
  15. ui::Layer* target_layer) {
  16. DCHECK(!copy_result->IsEmpty());
  17. DCHECK_EQ(copy_result->format(), viz::CopyOutputResult::Format::RGBA);
  18. DCHECK_EQ(copy_result->destination(),
  19. viz::CopyOutputResult::Destination::kNativeTextures);
  20. const gpu::MailboxHolder& plane = copy_result->GetTextureResult()->planes[0];
  21. viz::TransferableResource transferable_resource =
  22. viz::TransferableResource::MakeGL(plane.mailbox, GL_LINEAR,
  23. plane.texture_target, plane.sync_token,
  24. copy_result->size(),
  25. /*is_overlay_candidate=*/false);
  26. viz::CopyOutputResult::ReleaseCallbacks release_callbacks =
  27. copy_result->TakeTextureOwnership();
  28. // CopyOutputResults carrying RGBA format contain a single texture, there
  29. // should be only one release callback when a result is not empty:
  30. DCHECK_EQ(1u, release_callbacks.size());
  31. viz::ReleaseCallback release_callback = std::move(release_callbacks[0]);
  32. target_layer->SetTransferableResource(
  33. transferable_resource, std::move(release_callback), target_layer->size());
  34. }
  35. void CopyToNewLayerOnCopyRequestFinished(
  36. LayerCopyCallback layer_copy_callback,
  37. const gfx::Size& layer_size,
  38. std::unique_ptr<viz::CopyOutputResult> copy_result) {
  39. if (!copy_result || copy_result->IsEmpty()) {
  40. if (!layer_copy_callback.MaybeValid())
  41. return;
  42. std::move(layer_copy_callback).Run(nullptr);
  43. return;
  44. }
  45. auto copy_layer =
  46. CreateLayerFromCopyOutputResult(std::move(copy_result), layer_size);
  47. std::move(layer_copy_callback).Run(std::move(copy_layer));
  48. }
  49. void CopyToLayerOnCopyRequestFinished(
  50. GetTargetLayerCallback get_target_layer_callback,
  51. std::unique_ptr<viz::CopyOutputResult> copy_result) {
  52. if (get_target_layer_callback.IsCancelled())
  53. return;
  54. if (!copy_result || copy_result->IsEmpty())
  55. return;
  56. ui::Layer* layer = nullptr;
  57. std::move(get_target_layer_callback).Run(&layer);
  58. if (!layer)
  59. return;
  60. CopyCopyOutputResultToLayer(std::move(copy_result), layer);
  61. }
  62. } // namespace
  63. std::unique_ptr<ui::Layer> CreateLayerFromCopyOutputResult(
  64. std::unique_ptr<viz::CopyOutputResult> copy_result,
  65. const gfx::Size& layer_size) {
  66. auto copy_layer = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  67. copy_layer->SetBounds(gfx::Rect(layer_size));
  68. CopyCopyOutputResultToLayer(std::move(copy_result), copy_layer.get());
  69. return copy_layer;
  70. }
  71. void CopyLayerContentToNewLayer(ui::Layer* layer, LayerCopyCallback callback) {
  72. auto new_callback = base::BindOnce(&CopyToNewLayerOnCopyRequestFinished,
  73. std::move(callback), layer->size());
  74. auto copy_request = std::make_unique<viz::CopyOutputRequest>(
  75. viz::CopyOutputRequest::ResultFormat::RGBA,
  76. viz::CopyOutputRequest::ResultDestination::kNativeTextures,
  77. std::move(new_callback));
  78. gfx::Rect bounds(layer->size());
  79. copy_request->set_area(bounds);
  80. copy_request->set_result_selection(bounds);
  81. layer->RequestCopyOfOutput(std::move(copy_request));
  82. }
  83. void CopyLayerContentToLayer(ui::Layer* layer,
  84. GetTargetLayerCallback callback) {
  85. auto new_callback =
  86. base::BindOnce(&CopyToLayerOnCopyRequestFinished, std::move(callback));
  87. auto copy_request = std::make_unique<viz::CopyOutputRequest>(
  88. viz::CopyOutputRequest::ResultFormat::RGBA,
  89. viz::CopyOutputRequest::ResultDestination::kNativeTextures,
  90. std::move(new_callback));
  91. gfx::Rect bounds(layer->size());
  92. copy_request->set_area(bounds);
  93. copy_request->set_result_selection(bounds);
  94. layer->RequestCopyOfOutput(std::move(copy_request));
  95. }
  96. } // namespace ash