2018-12-10 10:41:08 -08:00
|
|
|
/*
|
|
|
|
* Copyright 2018 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
|
2018-12-10 10:41:08 -08:00
|
|
|
#include <android/native_window.h>
|
|
|
|
#include <android/surface_control.h>
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
#include <configstore/Utils.h>
|
|
|
|
|
|
|
|
#include <gui/HdrMetadata.h>
|
|
|
|
#include <gui/ISurfaceComposer.h>
|
2018-12-10 10:41:08 -08:00
|
|
|
#include <gui/Surface.h>
|
|
|
|
#include <gui/SurfaceComposerClient.h>
|
|
|
|
#include <gui/SurfaceControl.h>
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
#include <ui/HdrCapabilities.h>
|
|
|
|
|
|
|
|
#include <utils/Timers.h>
|
|
|
|
|
|
|
|
using namespace android::hardware::configstore;
|
|
|
|
using namespace android::hardware::configstore::V1_0;
|
2018-12-10 10:41:08 -08:00
|
|
|
using namespace android;
|
2019-01-18 16:14:04 -08:00
|
|
|
using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
|
2018-12-10 10:41:08 -08:00
|
|
|
|
|
|
|
using Transaction = SurfaceComposerClient::Transaction;
|
|
|
|
|
|
|
|
#define CHECK_NOT_NULL(name) \
|
|
|
|
LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument");
|
|
|
|
|
|
|
|
#define CHECK_VALID_RECT(name) \
|
|
|
|
LOG_ALWAYS_FATAL_IF(!static_cast<const Rect&>(name).isValid(), \
|
|
|
|
"invalid arg passed as " #name " argument");
|
|
|
|
|
2019-01-22 17:39:43 -08:00
|
|
|
static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
|
|
|
|
sp<SurfaceComposerClient> client = surfaceControl->getClient();
|
2019-01-25 02:56:41 -08:00
|
|
|
|
|
|
|
const sp<IBinder> display = client->getInternalDisplayToken();
|
|
|
|
if (display == nullptr) {
|
|
|
|
ALOGE("unable to get wide color support for disconnected internal display");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-01-24 17:49:46 -08:00
|
|
|
bool isWideColorDisplay = false;
|
|
|
|
status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
|
2019-01-22 17:39:43 -08:00
|
|
|
if (err) {
|
|
|
|
ALOGE("unable to get wide color support");
|
|
|
|
return false;
|
|
|
|
}
|
2019-01-24 17:49:46 -08:00
|
|
|
return isWideColorDisplay;
|
2019-01-22 17:39:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
|
|
|
|
sp<SurfaceComposerClient> client = surfaceControl->getClient();
|
2019-01-25 02:56:41 -08:00
|
|
|
|
|
|
|
const sp<IBinder> display = client->getInternalDisplayToken();
|
|
|
|
if (display == nullptr) {
|
|
|
|
ALOGE("unable to get hdr capabilities for disconnected internal display");
|
|
|
|
return false;
|
|
|
|
}
|
2019-01-22 17:39:43 -08:00
|
|
|
|
|
|
|
HdrCapabilities hdrCapabilities;
|
|
|
|
status_t err = client->getHdrCapabilities(display, &hdrCapabilities);
|
|
|
|
if (err) {
|
|
|
|
ALOGE("unable to get hdr capabilities");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !hdrCapabilities.getSupportedHdrTypes().empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isDataSpaceValid(const sp<SurfaceControl>& surfaceControl, ADataSpace dataSpace) {
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN));
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_SCRGB_LINEAR) == static_cast<int>(HAL_DATASPACE_V0_SCRGB_LINEAR));
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB));
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
|
|
|
|
static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
|
|
|
|
|
|
|
|
switch (static_cast<android_dataspace_t>(dataSpace)) {
|
|
|
|
case HAL_DATASPACE_UNKNOWN:
|
|
|
|
case HAL_DATASPACE_V0_SRGB:
|
|
|
|
return true;
|
|
|
|
// These data space need wide gamut support.
|
|
|
|
case HAL_DATASPACE_V0_SCRGB_LINEAR:
|
|
|
|
case HAL_DATASPACE_V0_SCRGB:
|
|
|
|
case HAL_DATASPACE_DISPLAY_P3:
|
|
|
|
return getWideColorSupport(surfaceControl);
|
|
|
|
// These data space need HDR support.
|
|
|
|
case HAL_DATASPACE_BT2020_PQ:
|
2019-08-26 12:48:49 -07:00
|
|
|
if (!getHdrSupport(surfaceControl)) {
|
|
|
|
ALOGE("Invalid dataspace - device does not support hdr");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2019-01-22 17:39:43 -08:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-10 10:41:08 -08:00
|
|
|
Transaction* ASurfaceTransaction_to_Transaction(ASurfaceTransaction* aSurfaceTransaction) {
|
|
|
|
return reinterpret_cast<Transaction*>(aSurfaceTransaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
SurfaceControl* ASurfaceControl_to_SurfaceControl(ASurfaceControl* aSurfaceControl) {
|
|
|
|
return reinterpret_cast<SurfaceControl*>(aSurfaceControl);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceControl_acquire(SurfaceControl* surfaceControl) {
|
|
|
|
// incStrong/decStrong token must be the same, doesn't matter what it is
|
|
|
|
surfaceControl->incStrong((void*)SurfaceControl_acquire);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceControl_release(SurfaceControl* surfaceControl) {
|
|
|
|
// incStrong/decStrong token must be the same, doesn't matter what it is
|
|
|
|
surfaceControl->decStrong((void*)SurfaceControl_acquire);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* window, const char* debug_name) {
|
|
|
|
CHECK_NOT_NULL(window);
|
|
|
|
CHECK_NOT_NULL(debug_name);
|
|
|
|
|
|
|
|
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
|
|
|
|
if (client->initCheck() != NO_ERROR) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
|
|
|
|
sp<SurfaceControl> surfaceControl =
|
|
|
|
client->createWithSurfaceParent(String8(debug_name), 0 /* width */, 0 /* height */,
|
|
|
|
// Format is only relevant for buffer queue layers.
|
|
|
|
PIXEL_FORMAT_UNKNOWN /* format */, flags,
|
|
|
|
static_cast<Surface*>(window));
|
|
|
|
if (!surfaceControl) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SurfaceControl_acquire(surfaceControl.get());
|
|
|
|
return reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
ASurfaceControl* ASurfaceControl_create(ASurfaceControl* parent, const char* debug_name) {
|
|
|
|
CHECK_NOT_NULL(parent);
|
|
|
|
CHECK_NOT_NULL(debug_name);
|
|
|
|
|
|
|
|
SurfaceComposerClient* client = ASurfaceControl_to_SurfaceControl(parent)->getClient().get();
|
|
|
|
|
|
|
|
SurfaceControl* surfaceControlParent = ASurfaceControl_to_SurfaceControl(parent);
|
|
|
|
|
|
|
|
uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
|
|
|
|
sp<SurfaceControl> surfaceControl =
|
|
|
|
client->createSurface(String8(debug_name), 0 /* width */, 0 /* height */,
|
|
|
|
// Format is only relevant for buffer queue layers.
|
|
|
|
PIXEL_FORMAT_UNKNOWN /* format */, flags,
|
|
|
|
surfaceControlParent);
|
|
|
|
if (!surfaceControl) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SurfaceControl_acquire(surfaceControl.get());
|
|
|
|
return reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) {
|
2018-12-10 10:41:08 -08:00
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
|
|
|
|
SurfaceControl_release(surfaceControl.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
ASurfaceTransaction* ASurfaceTransaction_create() {
|
|
|
|
Transaction* transaction = new Transaction;
|
|
|
|
return reinterpret_cast<ASurfaceTransaction*>(transaction);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) {
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
delete transaction;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_apply(ASurfaceTransaction* aSurfaceTransaction) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->apply();
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
typedef struct ASurfaceControlStats {
|
|
|
|
int64_t acquireTime;
|
|
|
|
sp<Fence> previousReleaseFence;
|
|
|
|
} ASurfaceControlStats;
|
|
|
|
|
|
|
|
struct ASurfaceTransactionStats {
|
|
|
|
std::unordered_map<ASurfaceControl*, ASurfaceControlStats> aSurfaceControlStats;
|
|
|
|
int64_t latchTime;
|
|
|
|
sp<Fence> presentFence;
|
|
|
|
};
|
|
|
|
|
|
|
|
int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurfaceTransactionStats) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransactionStats);
|
|
|
|
return aSurfaceTransactionStats->latchTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* aSurfaceTransactionStats) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransactionStats);
|
|
|
|
auto& presentFence = aSurfaceTransactionStats->presentFence;
|
|
|
|
return (presentFence) ? presentFence->dup() : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransactionStats_getASurfaceControls(ASurfaceTransactionStats* aSurfaceTransactionStats,
|
|
|
|
ASurfaceControl*** outASurfaceControls,
|
|
|
|
size_t* outASurfaceControlsSize) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransactionStats);
|
|
|
|
CHECK_NOT_NULL(outASurfaceControls);
|
|
|
|
CHECK_NOT_NULL(outASurfaceControlsSize);
|
|
|
|
|
|
|
|
size_t size = aSurfaceTransactionStats->aSurfaceControlStats.size();
|
|
|
|
|
|
|
|
SurfaceControl** surfaceControls = new SurfaceControl*[size];
|
|
|
|
ASurfaceControl** aSurfaceControls = reinterpret_cast<ASurfaceControl**>(surfaceControls);
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
for (auto& [aSurfaceControl, aSurfaceControlStats] : aSurfaceTransactionStats->aSurfaceControlStats) {
|
|
|
|
aSurfaceControls[i] = aSurfaceControl;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*outASurfaceControls = aSurfaceControls;
|
|
|
|
*outASurfaceControlsSize = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t ASurfaceTransactionStats_getAcquireTime(ASurfaceTransactionStats* aSurfaceTransactionStats,
|
|
|
|
ASurfaceControl* aSurfaceControl) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransactionStats);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
const auto& aSurfaceControlStats =
|
|
|
|
aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
|
|
|
|
LOG_ALWAYS_FATAL_IF(
|
|
|
|
aSurfaceControlStats == aSurfaceTransactionStats->aSurfaceControlStats.end(),
|
|
|
|
"ASurfaceControl not found");
|
|
|
|
|
|
|
|
return aSurfaceControlStats->second.acquireTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ASurfaceTransactionStats_getPreviousReleaseFenceFd(
|
|
|
|
ASurfaceTransactionStats* aSurfaceTransactionStats, ASurfaceControl* aSurfaceControl) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransactionStats);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
const auto& aSurfaceControlStats =
|
|
|
|
aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
|
|
|
|
LOG_ALWAYS_FATAL_IF(
|
|
|
|
aSurfaceControlStats == aSurfaceTransactionStats->aSurfaceControlStats.end(),
|
|
|
|
"ASurfaceControl not found");
|
|
|
|
|
|
|
|
auto& previousReleaseFence = aSurfaceControlStats->second.previousReleaseFence;
|
|
|
|
return (previousReleaseFence) ? previousReleaseFence->dup() : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** aSurfaceControls) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceControls);
|
|
|
|
|
|
|
|
SurfaceControl** surfaceControls = reinterpret_cast<SurfaceControl**>(aSurfaceControls);
|
|
|
|
delete[] surfaceControls;
|
|
|
|
}
|
|
|
|
|
2018-12-10 10:41:08 -08:00
|
|
|
void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction, void* context,
|
|
|
|
ASurfaceTransaction_OnComplete func) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(context);
|
|
|
|
CHECK_NOT_NULL(func);
|
|
|
|
|
|
|
|
TransactionCompletedCallbackTakesContext callback = [func](void* callback_context,
|
2019-01-18 16:14:04 -08:00
|
|
|
nsecs_t latchTime,
|
|
|
|
const sp<Fence>& presentFence,
|
|
|
|
const std::vector<SurfaceControlStats>& surfaceControlStats) {
|
|
|
|
ASurfaceTransactionStats aSurfaceTransactionStats;
|
|
|
|
|
|
|
|
aSurfaceTransactionStats.latchTime = latchTime;
|
|
|
|
aSurfaceTransactionStats.presentFence = presentFence;
|
|
|
|
|
|
|
|
auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
|
|
|
|
|
2020-01-29 14:27:09 -08:00
|
|
|
for (const auto& [surfaceControl, latchTime, acquireTime, presentFence, previousReleaseFence, transformHint, frameEvents] : surfaceControlStats) {
|
2019-01-18 16:14:04 -08:00
|
|
|
ASurfaceControl* aSurfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
|
|
|
|
aSurfaceControlStats[aSurfaceControl].acquireTime = acquireTime;
|
|
|
|
aSurfaceControlStats[aSurfaceControl].previousReleaseFence = previousReleaseFence;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*func)(callback_context, &aSurfaceTransactionStats);
|
2018-12-10 10:41:08 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->addTransactionCompletedCallback(callback, context);
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceTransaction_reparent(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
ASurfaceControl* newParentASurfaceControl) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
sp<SurfaceControl> newParentSurfaceControl = ASurfaceControl_to_SurfaceControl(
|
|
|
|
newParentASurfaceControl);
|
|
|
|
sp<IBinder> newParentHandle = (newParentSurfaceControl)? newParentSurfaceControl->getHandle() : nullptr;
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->reparent(surfaceControl, newParentHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_setVisibility(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
2018-12-10 10:41:08 -08:00
|
|
|
int8_t visibility) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
switch (visibility) {
|
|
|
|
case ASURFACE_TRANSACTION_VISIBILITY_SHOW:
|
|
|
|
transaction->show(surfaceControl);
|
|
|
|
break;
|
|
|
|
case ASURFACE_TRANSACTION_VISIBILITY_HIDE:
|
|
|
|
transaction->hide(surfaceControl);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
LOG_ALWAYS_FATAL("invalid visibility %d", visibility);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceTransaction_setZOrder(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
2018-12-10 10:41:08 -08:00
|
|
|
int32_t z_order) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->setLayer(surfaceControl, z_order);
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
AHardwareBuffer* buffer, int acquire_fence_fd) {
|
2018-12-10 10:41:08 -08:00
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
sp<GraphicBuffer> graphic_buffer(reinterpret_cast<GraphicBuffer*>(buffer));
|
|
|
|
|
|
|
|
transaction->setBuffer(surfaceControl, graphic_buffer);
|
2019-01-18 16:14:04 -08:00
|
|
|
if (acquire_fence_fd != -1) {
|
|
|
|
sp<Fence> fence = new Fence(acquire_fence_fd);
|
2018-12-10 10:41:08 -08:00
|
|
|
transaction->setAcquireFence(surfaceControl, fence);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl, const ARect& source,
|
|
|
|
const ARect& destination, int32_t transform) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
CHECK_VALID_RECT(source);
|
|
|
|
CHECK_VALID_RECT(destination);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->setCrop(surfaceControl, static_cast<const Rect&>(source));
|
|
|
|
transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));
|
|
|
|
transaction->setTransform(surfaceControl, transform);
|
2019-05-23 16:27:45 +08:00
|
|
|
bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
|
|
|
|
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
|
|
|
|
transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
|
2018-12-10 10:41:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
int8_t transparency) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
uint32_t flags = (transparency == ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE) ?
|
|
|
|
layer_state_t::eLayerOpaque : 0;
|
|
|
|
transaction->setFlags(surfaceControl, flags, layer_state_t::eLayerOpaque);
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
2018-12-10 10:41:08 -08:00
|
|
|
const ARect rects[], uint32_t count) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
Region region;
|
|
|
|
for (uint32_t i = 0; i < count; ++i) {
|
ASurfaceControl: fix surface damage
There are two problems with surface control.
1) By merging the rects, the Region turned into 0,0,0,0 instead of
an or of the Rects.
2) In the case where an app intends to have a region of 0,0,0,0,
we should treat it the same as a region of 0,0,-1,-1.
Bug: 131175047
Test: ASurfaceControl
Change-Id: Ib2e3b90ac215e069d3d3c2eca81ff1013b4287aa
2019-04-23 14:10:15 -07:00
|
|
|
region.orSelf(static_cast<const Rect&>(rects[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hardware composer interprets a DamageRegion with a single Rect of {0,0,0,0} to be an
|
|
|
|
// undamaged region and {0,0,-1,-1} to be a fully damaged buffer. This is a confusing
|
|
|
|
// distinction for a public api. Instead, default both cases to be a fully damaged buffer.
|
|
|
|
if (count == 1 && region.getBounds().isEmpty()) {
|
|
|
|
transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
|
|
|
|
return;
|
2018-12-10 10:41:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
transaction->setSurfaceDamageRegion(surfaceControl, region);
|
|
|
|
}
|
2019-01-18 16:14:04 -08:00
|
|
|
|
|
|
|
void ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
int64_t desiredPresentTime) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->setDesiredPresentTime(static_cast<nsecs_t>(desiredPresentTime));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
float alpha) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
LOG_ALWAYS_FATAL_IF(alpha < 0.0 || alpha > 1.0, "invalid alpha");
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
transaction->setAlpha(surfaceControl, alpha);
|
|
|
|
}
|
|
|
|
|
2019-02-07 14:06:04 -08:00
|
|
|
void ASurfaceTransaction_setBufferDataSpace(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
ADataSpace aDataSpace) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
2019-08-26 12:48:49 -07:00
|
|
|
if (!isDataSpaceValid(surfaceControl, aDataSpace)) {
|
|
|
|
ALOGE("Failed to set buffer dataspace - invalid dataspace");
|
|
|
|
return;
|
|
|
|
}
|
2019-02-07 14:06:04 -08:00
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
transaction->setDataspace(surfaceControl, static_cast<ui::Dataspace>(aDataSpace));
|
|
|
|
}
|
|
|
|
|
2019-01-18 16:14:04 -08:00
|
|
|
void ASurfaceTransaction_setHdrMetadata_smpte2086(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
struct AHdrMetadata_smpte2086* metadata) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
HdrMetadata hdrMetadata;
|
|
|
|
|
|
|
|
if (metadata) {
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryRed.x = metadata->displayPrimaryRed.x;
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryRed.y = metadata->displayPrimaryRed.y;
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryGreen.x = metadata->displayPrimaryGreen.x;
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryGreen.y = metadata->displayPrimaryGreen.y;
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryBlue.x = metadata->displayPrimaryBlue.x;
|
|
|
|
hdrMetadata.smpte2086.displayPrimaryBlue.y = metadata->displayPrimaryBlue.y;
|
|
|
|
hdrMetadata.smpte2086.whitePoint.x = metadata->whitePoint.x;
|
|
|
|
hdrMetadata.smpte2086.whitePoint.y = metadata->whitePoint.y;
|
|
|
|
hdrMetadata.smpte2086.minLuminance = metadata->minLuminance;
|
|
|
|
hdrMetadata.smpte2086.maxLuminance = metadata->maxLuminance;
|
|
|
|
|
|
|
|
hdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
|
|
|
|
} else {
|
|
|
|
hdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086;
|
|
|
|
}
|
|
|
|
|
|
|
|
transaction->setHdrMetadata(surfaceControl, hdrMetadata);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
struct AHdrMetadata_cta861_3* metadata) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
HdrMetadata hdrMetadata;
|
|
|
|
|
|
|
|
if (metadata) {
|
|
|
|
hdrMetadata.cta8613.maxContentLightLevel = metadata->maxContentLightLevel;
|
|
|
|
hdrMetadata.cta8613.maxFrameAverageLightLevel = metadata->maxFrameAverageLightLevel;
|
|
|
|
|
|
|
|
hdrMetadata.validTypes |= HdrMetadata::CTA861_3;
|
|
|
|
} else {
|
|
|
|
hdrMetadata.validTypes &= ~HdrMetadata::CTA861_3;
|
|
|
|
}
|
|
|
|
|
|
|
|
transaction->setHdrMetadata(surfaceControl, hdrMetadata);
|
|
|
|
}
|
2019-01-22 17:39:43 -08:00
|
|
|
|
|
|
|
void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
|
|
|
|
ASurfaceControl* aSurfaceControl,
|
|
|
|
float r, float g, float b, float alpha,
|
|
|
|
ADataSpace dataspace) {
|
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
|
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
2019-08-26 12:48:49 -07:00
|
|
|
if (!isDataSpaceValid(surfaceControl, dataspace)) {
|
|
|
|
ALOGE("Failed to set buffer dataspace - invalid dataspace");
|
|
|
|
return;
|
|
|
|
}
|
2019-01-22 17:39:43 -08:00
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
|
|
|
|
|
|
|
half3 color;
|
|
|
|
color.r = r;
|
|
|
|
color.g = g;
|
|
|
|
color.b = b;
|
|
|
|
|
2019-01-29 15:01:53 -08:00
|
|
|
transaction->setBackgroundColor(surfaceControl, color, alpha, static_cast<ui::Dataspace>(dataspace));
|
2019-01-22 17:39:43 -08:00
|
|
|
}
|
2020-01-14 11:37:21 -08:00
|
|
|
|
|
|
|
void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* aSurfaceTransaction,
|
2020-01-31 18:50:02 -08:00
|
|
|
ASurfaceControl* aSurfaceControl, float frameRate,
|
|
|
|
int8_t compatibility) {
|
2020-01-14 11:37:21 -08:00
|
|
|
CHECK_NOT_NULL(aSurfaceTransaction);
|
|
|
|
CHECK_NOT_NULL(aSurfaceControl);
|
|
|
|
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
|
2020-01-31 18:50:02 -08:00
|
|
|
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
|
|
|
|
transaction->setFrameRate(surfaceControl, frameRate, compatibility);
|
2020-01-14 11:37:21 -08:00
|
|
|
}
|