| // Copyright 2013 The Flutter 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 "flutter/impeller/toolkit/android/surface_transaction.h" |
| |
| #include "flutter/impeller/toolkit/android/hardware_buffer.h" |
| #include "flutter/impeller/toolkit/android/surface_control.h" |
| #include "impeller/base/validation.h" |
| |
| namespace impeller::android { |
| |
| SurfaceTransaction::SurfaceTransaction() |
| : transaction_(GetProcTable().ASurfaceTransaction_create()) {} |
| |
| SurfaceTransaction::~SurfaceTransaction() = default; |
| |
| bool SurfaceTransaction::IsValid() const { |
| return transaction_.is_valid(); |
| } |
| |
| struct TransactionInFlightData { |
| SurfaceTransaction::OnCompleteCallback callback; |
| }; |
| |
| bool SurfaceTransaction::Apply(OnCompleteCallback callback) { |
| if (!IsValid()) { |
| return false; |
| } |
| |
| if (!callback) { |
| callback = []() {}; |
| } |
| |
| const auto& proc_table = GetProcTable(); |
| |
| auto data = std::make_unique<TransactionInFlightData>(); |
| data->callback = callback; |
| proc_table.ASurfaceTransaction_setOnComplete( |
| transaction_.get(), // |
| data.release(), // |
| [](void* context, ASurfaceTransactionStats* stats) -> void { |
| auto data = reinterpret_cast<TransactionInFlightData*>(context); |
| data->callback(); |
| delete data; |
| }); |
| proc_table.ASurfaceTransaction_apply(transaction_.get()); |
| |
| // Transactions may not be applied over and over. |
| transaction_.reset(); |
| return true; |
| } |
| |
| bool SurfaceTransaction::SetContents(const SurfaceControl* control, |
| const HardwareBuffer* buffer) { |
| if (control == nullptr || buffer == nullptr) { |
| VALIDATION_LOG << "Invalid control or buffer."; |
| return false; |
| } |
| GetProcTable().ASurfaceTransaction_setBuffer(transaction_.get(), // |
| control->GetHandle(), // |
| buffer->GetHandle(), // |
| -1); |
| return true; |
| } |
| |
| bool SurfaceTransaction::SetBackgroundColor(const SurfaceControl& control, |
| const Color& color) { |
| if (!IsValid() || !control.IsValid()) { |
| return false; |
| } |
| GetProcTable().ASurfaceTransaction_setColor(transaction_.get(), // |
| control.GetHandle(), // |
| color.red, // |
| color.green, // |
| color.blue, // |
| color.alpha, // |
| ADATASPACE_SRGB_LINEAR // |
| ); |
| return true; |
| } |
| |
| bool SurfaceTransaction::SetParent(const SurfaceControl& control, |
| const SurfaceControl* new_parent) { |
| if (!IsValid() || !control.IsValid()) { |
| return false; |
| } |
| if (new_parent && !new_parent->IsValid()) { |
| return false; |
| } |
| GetProcTable().ASurfaceTransaction_reparent( |
| transaction_.get(), // |
| control.GetHandle(), // |
| new_parent == nullptr ? nullptr : new_parent->GetHandle() // |
| ); |
| return true; |
| } |
| |
| bool SurfaceTransaction::IsAvailableOnPlatform() { |
| return GetProcTable().IsValid() && |
| GetProcTable().ASurfaceTransaction_create.IsAvailable(); |
| } |
| |
| } // namespace impeller::android |