| // 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 |