summaryrefslogtreecommitdiff
path: root/native/android/surface_control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/android/surface_control.cpp')
-rw-r--r--native/android/surface_control.cpp87
1 files changed, 74 insertions, 13 deletions
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index e0f637959cfb..087837a5c70f 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -260,6 +260,7 @@ struct ASurfaceTransactionStats {
std::unordered_map<ASurfaceControl*, ASurfaceControlStats> aSurfaceControlStats;
int64_t latchTime;
sp<Fence> presentFence;
+ bool transactionCompleted;
};
int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurfaceTransactionStats) {
@@ -269,6 +270,9 @@ int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurface
int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* aSurfaceTransactionStats) {
CHECK_NOT_NULL(aSurfaceTransactionStats);
+ LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
+ "ASurfaceTransactionStats queried from an incomplete transaction callback");
+
auto& presentFence = aSurfaceTransactionStats->presentFence;
return (presentFence) ? presentFence->dup() : -1;
}
@@ -313,6 +317,8 @@ int ASurfaceTransactionStats_getPreviousReleaseFenceFd(
ASurfaceTransactionStats* aSurfaceTransactionStats, ASurfaceControl* aSurfaceControl) {
CHECK_NOT_NULL(aSurfaceTransactionStats);
CHECK_NOT_NULL(aSurfaceControl);
+ LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
+ "ASurfaceTransactionStats queried from an incomplete transaction callback");
const auto& aSurfaceControlStats =
aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
@@ -334,7 +340,6 @@ void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** aSurface
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,
@@ -345,6 +350,7 @@ void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction,
aSurfaceTransactionStats.latchTime = latchTime;
aSurfaceTransactionStats.presentFence = presentFence;
+ aSurfaceTransactionStats.transactionCompleted = true;
auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
@@ -432,46 +438,58 @@ void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction,
const ARect& destination, int32_t transform) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
- CHECK_VALID_RECT(source);
CHECK_VALID_RECT(destination);
+ Rect sourceRect = static_cast<const Rect&>(source);
+ // Adjust the source so its top and left are not negative
+ sourceRect.left = std::max(sourceRect.left, 0);
+ sourceRect.top = std::max(sourceRect.top, 0);
+ LOG_ALWAYS_FATAL_IF(sourceRect.isEmpty(), "invalid arg passed as source argument");
+
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->setCrop(surfaceControl, sourceRect);
+
+ float dsdx = (destination.right - destination.left) /
+ static_cast<float>(sourceRect.right - sourceRect.left);
+ float dsdy = (destination.bottom - destination.top) /
+ static_cast<float>(sourceRect.bottom - sourceRect.top);
+
+ transaction->setPosition(surfaceControl, destination.left - (sourceRect.left * dsdx),
+ destination.top - (sourceRect.top * dsdy));
+ transaction->setMatrix(surfaceControl, dsdx, 0, 0, dsdy);
transaction->setTransform(surfaceControl, transform);
bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
}
-void ASurfaceTransaction_setSourceRect(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl, const ARect& source) {
+void ASurfaceTransaction_setCrop(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl, const ARect& crop) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
- CHECK_VALID_RECT(source);
+ CHECK_VALID_RECT(crop);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
- transaction->setCrop(surfaceControl, static_cast<const Rect&>(source));
+ transaction->setCrop(surfaceControl, static_cast<const Rect&>(crop));
}
void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl, const ARect& destination) {
+ ASurfaceControl* aSurfaceControl, int32_t x, int32_t y) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
- CHECK_VALID_RECT(destination);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
- transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));
+ transaction->setPosition(surfaceControl, x, y);
}
-void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl, int32_t transform) {
+void ASurfaceTransaction_setBufferTransform(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl, int32_t transform) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
@@ -484,6 +502,19 @@ void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction,
transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
}
+void ASurfaceTransaction_setScale(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl, float xScale, float yScale) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(aSurfaceControl);
+ LOG_ALWAYS_FATAL_IF(xScale < 0, "negative value passed in for xScale");
+ LOG_ALWAYS_FATAL_IF(yScale < 0, "negative value passed in for yScale");
+
+ sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ transaction->setMatrix(surfaceControl, xScale, 0, 0, yScale);
+}
+
void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
int8_t transparency) {
@@ -670,3 +701,33 @@ void ASurfaceTransaction_setEnableBackPressure(ASurfaceTransaction* aSurfaceTran
layer_state_t::eEnableBackpressure : 0;
transaction->setFlags(surfaceControl, flags, layer_state_t::eEnableBackpressure);
}
+
+void ASurfaceTransaction_setOnCommit(ASurfaceTransaction* aSurfaceTransaction, void* context,
+ ASurfaceTransaction_OnCommit func) {
+ CHECK_NOT_NULL(aSurfaceTransaction);
+ CHECK_NOT_NULL(func);
+
+ TransactionCompletedCallbackTakesContext callback =
+ [func](void* callback_context, nsecs_t latchTime, const sp<Fence>& /* presentFence */,
+ const std::vector<SurfaceControlStats>& surfaceControlStats) {
+ ASurfaceTransactionStats aSurfaceTransactionStats;
+ aSurfaceTransactionStats.latchTime = latchTime;
+ aSurfaceTransactionStats.transactionCompleted = false;
+
+ auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
+ for (const auto&
+ [surfaceControl, latchTime, acquireTime, presentFence,
+ previousReleaseFence, transformHint,
+ frameEvents] : surfaceControlStats) {
+ ASurfaceControl* aSurfaceControl =
+ reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
+ aSurfaceControlStats[aSurfaceControl].acquireTime = acquireTime;
+ }
+
+ (*func)(callback_context, &aSurfaceTransactionStats);
+ };
+
+ Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
+
+ transaction->addTransactionCommittedCallback(callback, context);
+} \ No newline at end of file