blob: a8c2ea544d38c5ae32f2a780229124c31b30bdbd [file] [log] [blame]
Marissa Wallf6a73fa2018-12-10 10:41:08 -08001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Marissa Wall1be5a102019-01-18 16:14:04 -080017#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
Marissa Wallf6a73fa2018-12-10 10:41:08 -080018#include <android/native_window.h>
19#include <android/surface_control.h>
Jorim Jaggi71db8892021-02-03 23:19:29 +010020#include <surface_control_private.h>
Marissa Wallf6a73fa2018-12-10 10:41:08 -080021
Marissa Wall1be5a102019-01-18 16:14:04 -080022#include <configstore/Utils.h>
23
24#include <gui/HdrMetadata.h>
25#include <gui/ISurfaceComposer.h>
Marissa Wallf6a73fa2018-12-10 10:41:08 -080026#include <gui/Surface.h>
27#include <gui/SurfaceComposerClient.h>
28#include <gui/SurfaceControl.h>
29
Marin Shalamanov463ad8e2021-01-28 22:58:37 +010030#include <ui/DynamicDisplayInfo.h>
Marissa Wall1be5a102019-01-18 16:14:04 -080031
32#include <utils/Timers.h>
33
34using namespace android::hardware::configstore;
35using namespace android::hardware::configstore::V1_0;
Marissa Wallf6a73fa2018-12-10 10:41:08 -080036using namespace android;
37
38using Transaction = SurfaceComposerClient::Transaction;
39
40#define CHECK_NOT_NULL(name) \
41 LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument");
42
43#define CHECK_VALID_RECT(name) \
44 LOG_ALWAYS_FATAL_IF(!static_cast<const Rect&>(name).isValid(), \
45 "invalid arg passed as " #name " argument");
46
Valerie Hau5bbfd512019-01-22 17:39:43 -080047static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
48 sp<SurfaceComposerClient> client = surfaceControl->getClient();
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080049
50 const sp<IBinder> display = client->getInternalDisplayToken();
51 if (display == nullptr) {
52 ALOGE("unable to get wide color support for disconnected internal display");
53 return false;
54 }
55
Peiyong Lin0d04f322019-01-24 17:49:46 -080056 bool isWideColorDisplay = false;
57 status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
Valerie Hau5bbfd512019-01-22 17:39:43 -080058 if (err) {
59 ALOGE("unable to get wide color support");
60 return false;
61 }
Peiyong Lin0d04f322019-01-24 17:49:46 -080062 return isWideColorDisplay;
Valerie Hau5bbfd512019-01-22 17:39:43 -080063}
64
65static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
66 sp<SurfaceComposerClient> client = surfaceControl->getClient();
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080067
68 const sp<IBinder> display = client->getInternalDisplayToken();
69 if (display == nullptr) {
70 ALOGE("unable to get hdr capabilities for disconnected internal display");
71 return false;
72 }
Valerie Hau5bbfd512019-01-22 17:39:43 -080073
Marin Shalamanov463ad8e2021-01-28 22:58:37 +010074 ui::DynamicDisplayInfo info;
75 if (status_t err = client->getDynamicDisplayInfo(display, &info); err != NO_ERROR) {
Valerie Hau5bbfd512019-01-22 17:39:43 -080076 ALOGE("unable to get hdr capabilities");
Marin Shalamanov463ad8e2021-01-28 22:58:37 +010077 return err;
Valerie Hau5bbfd512019-01-22 17:39:43 -080078 }
79
Marin Shalamanov463ad8e2021-01-28 22:58:37 +010080 return !info.hdrCapabilities.getSupportedHdrTypes().empty();
Valerie Hau5bbfd512019-01-22 17:39:43 -080081}
82
83static bool isDataSpaceValid(const sp<SurfaceControl>& surfaceControl, ADataSpace dataSpace) {
84 static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN));
85 static_assert(static_cast<int>(ADATASPACE_SCRGB_LINEAR) == static_cast<int>(HAL_DATASPACE_V0_SCRGB_LINEAR));
86 static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB));
87 static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
88 static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
89 static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
90
91 switch (static_cast<android_dataspace_t>(dataSpace)) {
92 case HAL_DATASPACE_UNKNOWN:
93 case HAL_DATASPACE_V0_SRGB:
94 return true;
95 // These data space need wide gamut support.
96 case HAL_DATASPACE_V0_SCRGB_LINEAR:
97 case HAL_DATASPACE_V0_SCRGB:
98 case HAL_DATASPACE_DISPLAY_P3:
99 return getWideColorSupport(surfaceControl);
100 // These data space need HDR support.
101 case HAL_DATASPACE_BT2020_PQ:
Valerie Hau5e18c432019-08-26 12:48:49 -0700102 if (!getHdrSupport(surfaceControl)) {
103 ALOGE("Invalid dataspace - device does not support hdr");
104 return false;
105 }
106 return true;
Valerie Hau5bbfd512019-01-22 17:39:43 -0800107 default:
108 return false;
109 }
110}
111
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800112Transaction* ASurfaceTransaction_to_Transaction(ASurfaceTransaction* aSurfaceTransaction) {
113 return reinterpret_cast<Transaction*>(aSurfaceTransaction);
114}
115
116SurfaceControl* ASurfaceControl_to_SurfaceControl(ASurfaceControl* aSurfaceControl) {
117 return reinterpret_cast<SurfaceControl*>(aSurfaceControl);
118}
119
120void SurfaceControl_acquire(SurfaceControl* surfaceControl) {
121 // incStrong/decStrong token must be the same, doesn't matter what it is
122 surfaceControl->incStrong((void*)SurfaceControl_acquire);
123}
124
125void SurfaceControl_release(SurfaceControl* surfaceControl) {
126 // incStrong/decStrong token must be the same, doesn't matter what it is
127 surfaceControl->decStrong((void*)SurfaceControl_acquire);
128}
129
130ASurfaceControl* ASurfaceControl_createFromWindow(ANativeWindow* window, const char* debug_name) {
131 CHECK_NOT_NULL(window);
132 CHECK_NOT_NULL(debug_name);
133
134 sp<SurfaceComposerClient> client = new SurfaceComposerClient();
135 if (client->initCheck() != NO_ERROR) {
136 return nullptr;
137 }
138
Vishnu Nairce1a6482020-10-22 17:41:30 -0700139 Surface* surface = static_cast<Surface*>(window);
140 sp<IBinder> parentHandle = surface->getSurfaceControlHandle();
141
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800142 uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
Vishnu Nairce1a6482020-10-22 17:41:30 -0700143 sp<SurfaceControl> surfaceControl;
144 if (parentHandle) {
145 surfaceControl =
146 client->createSurface(String8(debug_name), 0 /* width */, 0 /* height */,
147 // Format is only relevant for buffer queue layers.
148 PIXEL_FORMAT_UNKNOWN /* format */, flags, parentHandle);
149 } else {
150 surfaceControl =
151 client->createWithSurfaceParent(String8(debug_name), 0 /* width */, 0 /* height */,
152 // Format is only relevant for buffer queue layers.
153 PIXEL_FORMAT_UNKNOWN /* format */, flags,
154 static_cast<Surface*>(window));
155 }
156
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800157 if (!surfaceControl) {
158 return nullptr;
159 }
160
161 SurfaceControl_acquire(surfaceControl.get());
162 return reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
163}
164
165ASurfaceControl* ASurfaceControl_create(ASurfaceControl* parent, const char* debug_name) {
166 CHECK_NOT_NULL(parent);
167 CHECK_NOT_NULL(debug_name);
168
169 SurfaceComposerClient* client = ASurfaceControl_to_SurfaceControl(parent)->getClient().get();
170
171 SurfaceControl* surfaceControlParent = ASurfaceControl_to_SurfaceControl(parent);
172
173 uint32_t flags = ISurfaceComposerClient::eFXSurfaceBufferState;
174 sp<SurfaceControl> surfaceControl =
175 client->createSurface(String8(debug_name), 0 /* width */, 0 /* height */,
176 // Format is only relevant for buffer queue layers.
177 PIXEL_FORMAT_UNKNOWN /* format */, flags,
Vishnu Nairce1a6482020-10-22 17:41:30 -0700178 surfaceControlParent->getHandle());
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800179 if (!surfaceControl) {
180 return nullptr;
181 }
182
183 SurfaceControl_acquire(surfaceControl.get());
184 return reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
185}
186
Huihong Luo91697e12021-01-28 15:24:19 -0800187void ASurfaceControl_acquire(ASurfaceControl* aSurfaceControl) {
188 SurfaceControl* surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800189
Huihong Luo91697e12021-01-28 15:24:19 -0800190 SurfaceControl_acquire(surfaceControl);
191}
192
193void ASurfaceControl_release(ASurfaceControl* aSurfaceControl) {
194 SurfaceControl* surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
195
196 SurfaceControl_release(surfaceControl);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800197}
198
Jorim Jaggi71db8892021-02-03 23:19:29 +0100199struct ASurfaceControlStats {
200 int64_t acquireTime;
201 sp<Fence> previousReleaseFence;
202 uint64_t frameNumber;
203};
204
205void ASurfaceControl_registerSurfaceStatsListener(ASurfaceControl* control, void* context,
206 ASurfaceControl_SurfaceStatsListener func) {
207 SurfaceStatsCallback callback = [func](void* callback_context,
208 nsecs_t,
209 const sp<Fence>&,
210 const SurfaceStats& surfaceStats) {
211
212 ASurfaceControlStats aSurfaceControlStats;
213
214 ASurfaceControl* aSurfaceControl =
215 reinterpret_cast<ASurfaceControl*>(surfaceStats.surfaceControl.get());
216 aSurfaceControlStats.acquireTime = surfaceStats.acquireTime;
217 aSurfaceControlStats.previousReleaseFence = surfaceStats.previousReleaseFence;
218 aSurfaceControlStats.frameNumber = surfaceStats.eventStats.frameNumber;
219
220 (*func)(callback_context, aSurfaceControl, &aSurfaceControlStats);
221 };
222 TransactionCompletedListener::getInstance()->addSurfaceStatsListener(context,
223 reinterpret_cast<void*>(func), ASurfaceControl_to_SurfaceControl(control), callback);
224}
225
226
227void ASurfaceControl_unregisterSurfaceStatsListener(void* context,
228 ASurfaceControl_SurfaceStatsListener func) {
229 TransactionCompletedListener::getInstance()->removeSurfaceStatsListener(context,
230 reinterpret_cast<void*>(func));
231}
232
233int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats) {
234 return stats->acquireTime;
235}
236
237uint64_t ASurfaceControlStats_getFrameNumber(ASurfaceControlStats* stats) {
238 return stats->frameNumber;
239}
240
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800241ASurfaceTransaction* ASurfaceTransaction_create() {
242 Transaction* transaction = new Transaction;
243 return reinterpret_cast<ASurfaceTransaction*>(transaction);
244}
245
246void ASurfaceTransaction_delete(ASurfaceTransaction* aSurfaceTransaction) {
247 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
248 delete transaction;
249}
250
251void ASurfaceTransaction_apply(ASurfaceTransaction* aSurfaceTransaction) {
252 CHECK_NOT_NULL(aSurfaceTransaction);
253
254 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
255
256 transaction->apply();
257}
258
Marissa Wall1be5a102019-01-18 16:14:04 -0800259struct ASurfaceTransactionStats {
260 std::unordered_map<ASurfaceControl*, ASurfaceControlStats> aSurfaceControlStats;
261 int64_t latchTime;
262 sp<Fence> presentFence;
Vishnu Nairbeb3b482021-04-21 08:31:27 -0700263 bool transactionCompleted;
Marissa Wall1be5a102019-01-18 16:14:04 -0800264};
265
266int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* aSurfaceTransactionStats) {
267 CHECK_NOT_NULL(aSurfaceTransactionStats);
268 return aSurfaceTransactionStats->latchTime;
269}
270
271int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* aSurfaceTransactionStats) {
272 CHECK_NOT_NULL(aSurfaceTransactionStats);
Vishnu Nairbeb3b482021-04-21 08:31:27 -0700273 LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
274 "ASurfaceTransactionStats queried from an incomplete transaction callback");
275
Marissa Wall1be5a102019-01-18 16:14:04 -0800276 auto& presentFence = aSurfaceTransactionStats->presentFence;
277 return (presentFence) ? presentFence->dup() : -1;
278}
279
280void ASurfaceTransactionStats_getASurfaceControls(ASurfaceTransactionStats* aSurfaceTransactionStats,
281 ASurfaceControl*** outASurfaceControls,
282 size_t* outASurfaceControlsSize) {
283 CHECK_NOT_NULL(aSurfaceTransactionStats);
284 CHECK_NOT_NULL(outASurfaceControls);
285 CHECK_NOT_NULL(outASurfaceControlsSize);
286
287 size_t size = aSurfaceTransactionStats->aSurfaceControlStats.size();
288
289 SurfaceControl** surfaceControls = new SurfaceControl*[size];
290 ASurfaceControl** aSurfaceControls = reinterpret_cast<ASurfaceControl**>(surfaceControls);
291
292 size_t i = 0;
293 for (auto& [aSurfaceControl, aSurfaceControlStats] : aSurfaceTransactionStats->aSurfaceControlStats) {
294 aSurfaceControls[i] = aSurfaceControl;
295 i++;
296 }
297
298 *outASurfaceControls = aSurfaceControls;
299 *outASurfaceControlsSize = size;
300}
301
302int64_t ASurfaceTransactionStats_getAcquireTime(ASurfaceTransactionStats* aSurfaceTransactionStats,
303 ASurfaceControl* aSurfaceControl) {
304 CHECK_NOT_NULL(aSurfaceTransactionStats);
305 CHECK_NOT_NULL(aSurfaceControl);
306
307 const auto& aSurfaceControlStats =
308 aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
309 LOG_ALWAYS_FATAL_IF(
310 aSurfaceControlStats == aSurfaceTransactionStats->aSurfaceControlStats.end(),
311 "ASurfaceControl not found");
312
313 return aSurfaceControlStats->second.acquireTime;
314}
315
316int ASurfaceTransactionStats_getPreviousReleaseFenceFd(
317 ASurfaceTransactionStats* aSurfaceTransactionStats, ASurfaceControl* aSurfaceControl) {
318 CHECK_NOT_NULL(aSurfaceTransactionStats);
319 CHECK_NOT_NULL(aSurfaceControl);
Vishnu Nairbeb3b482021-04-21 08:31:27 -0700320 LOG_ALWAYS_FATAL_IF(!aSurfaceTransactionStats->transactionCompleted,
321 "ASurfaceTransactionStats queried from an incomplete transaction callback");
Marissa Wall1be5a102019-01-18 16:14:04 -0800322
323 const auto& aSurfaceControlStats =
324 aSurfaceTransactionStats->aSurfaceControlStats.find(aSurfaceControl);
325 LOG_ALWAYS_FATAL_IF(
326 aSurfaceControlStats == aSurfaceTransactionStats->aSurfaceControlStats.end(),
327 "ASurfaceControl not found");
328
329 auto& previousReleaseFence = aSurfaceControlStats->second.previousReleaseFence;
330 return (previousReleaseFence) ? previousReleaseFence->dup() : -1;
331}
332
333void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** aSurfaceControls) {
334 CHECK_NOT_NULL(aSurfaceControls);
335
336 SurfaceControl** surfaceControls = reinterpret_cast<SurfaceControl**>(aSurfaceControls);
337 delete[] surfaceControls;
338}
339
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800340void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction, void* context,
341 ASurfaceTransaction_OnComplete func) {
342 CHECK_NOT_NULL(aSurfaceTransaction);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800343 CHECK_NOT_NULL(func);
344
345 TransactionCompletedCallbackTakesContext callback = [func](void* callback_context,
Marissa Wall1be5a102019-01-18 16:14:04 -0800346 nsecs_t latchTime,
347 const sp<Fence>& presentFence,
348 const std::vector<SurfaceControlStats>& surfaceControlStats) {
349 ASurfaceTransactionStats aSurfaceTransactionStats;
350
351 aSurfaceTransactionStats.latchTime = latchTime;
352 aSurfaceTransactionStats.presentFence = presentFence;
Vishnu Nairbeb3b482021-04-21 08:31:27 -0700353 aSurfaceTransactionStats.transactionCompleted = true;
Marissa Wall1be5a102019-01-18 16:14:04 -0800354
355 auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
356
Valerie Haud6a222e2020-01-29 14:27:09 -0800357 for (const auto& [surfaceControl, latchTime, acquireTime, presentFence, previousReleaseFence, transformHint, frameEvents] : surfaceControlStats) {
Marissa Wall1be5a102019-01-18 16:14:04 -0800358 ASurfaceControl* aSurfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
359 aSurfaceControlStats[aSurfaceControl].acquireTime = acquireTime;
360 aSurfaceControlStats[aSurfaceControl].previousReleaseFence = previousReleaseFence;
361 }
362
363 (*func)(callback_context, &aSurfaceTransactionStats);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800364 };
365
366 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
367
368 transaction->addTransactionCompletedCallback(callback, context);
369}
370
Marissa Wall1be5a102019-01-18 16:14:04 -0800371void ASurfaceTransaction_reparent(ASurfaceTransaction* aSurfaceTransaction,
372 ASurfaceControl* aSurfaceControl,
373 ASurfaceControl* newParentASurfaceControl) {
374 CHECK_NOT_NULL(aSurfaceTransaction);
375 CHECK_NOT_NULL(aSurfaceControl);
376
377 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
378 sp<SurfaceControl> newParentSurfaceControl = ASurfaceControl_to_SurfaceControl(
379 newParentASurfaceControl);
Marissa Wall1be5a102019-01-18 16:14:04 -0800380 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
381
Pablo Gamito117040c2020-09-14 08:24:41 +0000382 transaction->reparent(surfaceControl, newParentSurfaceControl);
Marissa Wall1be5a102019-01-18 16:14:04 -0800383}
384
385void ASurfaceTransaction_setVisibility(ASurfaceTransaction* aSurfaceTransaction,
386 ASurfaceControl* aSurfaceControl,
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800387 int8_t visibility) {
388 CHECK_NOT_NULL(aSurfaceTransaction);
389 CHECK_NOT_NULL(aSurfaceControl);
390
391 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
392 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
393
394 switch (visibility) {
395 case ASURFACE_TRANSACTION_VISIBILITY_SHOW:
396 transaction->show(surfaceControl);
397 break;
398 case ASURFACE_TRANSACTION_VISIBILITY_HIDE:
399 transaction->hide(surfaceControl);
400 break;
401 default:
402 LOG_ALWAYS_FATAL("invalid visibility %d", visibility);
403 }
404}
405
Marissa Wall1be5a102019-01-18 16:14:04 -0800406void ASurfaceTransaction_setZOrder(ASurfaceTransaction* aSurfaceTransaction,
407 ASurfaceControl* aSurfaceControl,
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800408 int32_t z_order) {
409 CHECK_NOT_NULL(aSurfaceTransaction);
410 CHECK_NOT_NULL(aSurfaceControl);
411
412 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
413 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
414
415 transaction->setLayer(surfaceControl, z_order);
416}
417
Marissa Wall1be5a102019-01-18 16:14:04 -0800418void ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
419 ASurfaceControl* aSurfaceControl,
420 AHardwareBuffer* buffer, int acquire_fence_fd) {
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800421 CHECK_NOT_NULL(aSurfaceTransaction);
422 CHECK_NOT_NULL(aSurfaceControl);
423
424 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
425 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
426
427 sp<GraphicBuffer> graphic_buffer(reinterpret_cast<GraphicBuffer*>(buffer));
428
429 transaction->setBuffer(surfaceControl, graphic_buffer);
Marissa Wall1be5a102019-01-18 16:14:04 -0800430 if (acquire_fence_fd != -1) {
431 sp<Fence> fence = new Fence(acquire_fence_fd);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800432 transaction->setAcquireFence(surfaceControl, fence);
433 }
434}
435
436void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction,
437 ASurfaceControl* aSurfaceControl, const ARect& source,
438 const ARect& destination, int32_t transform) {
439 CHECK_NOT_NULL(aSurfaceTransaction);
440 CHECK_NOT_NULL(aSurfaceControl);
chaviw87a07ea2021-04-29 09:04:41 -0500441 CHECK_VALID_RECT(source);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800442 CHECK_VALID_RECT(destination);
443
444 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
445 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
446
chaviw87a07ea2021-04-29 09:04:41 -0500447 Rect sourceRect = static_cast<const Rect&>(source);
448 Rect destRect = static_cast<const Rect&>(destination);
449 // Adjust the source so its top and left are not negative
450 sourceRect.left = std::max(sourceRect.left, 0);
451 sourceRect.top = std::max(sourceRect.top, 0);
452
453 if (!sourceRect.isValid()) {
454 sourceRect.makeInvalid();
455 }
chaviw9b2ac242021-04-27 15:52:09 -0500456 transaction->setBufferCrop(surfaceControl, sourceRect);
Chavi Weingarten305ec1d2021-04-09 13:37:33 +0000457
chaviw87a07ea2021-04-29 09:04:41 -0500458 int destW = destRect.width();
459 int destH = destRect.height();
460 if (destRect.left < 0) {
461 destRect.left = 0;
462 destRect.right = destW;
463 }
464 if (destRect.top < 0) {
465 destRect.top = 0;
466 destRect.bottom = destH;
467 }
Chavi Weingarten305ec1d2021-04-09 13:37:33 +0000468
chaviw87a07ea2021-04-29 09:04:41 -0500469 if (!sourceRect.isEmpty()) {
470 float sx = destW / static_cast<float>(sourceRect.width());
471 float sy = destH / static_cast<float>(sourceRect.height());
472 transaction->setPosition(surfaceControl, destRect.left - (sourceRect.left * sx),
473 destRect.top - (sourceRect.top * sy));
474 transaction->setMatrix(surfaceControl, sx, 0, 0, sy);
475 } else {
476 transaction->setPosition(surfaceControl, destRect.left, destRect.top);
477 }
478
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800479 transaction->setTransform(surfaceControl, transform);
Vishnu Nair1ad69542019-05-23 16:27:45 +0800480 bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
481 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
482 transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800483}
484
chaviwccf3e8b2021-03-25 15:28:44 -0500485void ASurfaceTransaction_setCrop(ASurfaceTransaction* aSurfaceTransaction,
486 ASurfaceControl* aSurfaceControl, const ARect& crop) {
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500487 CHECK_NOT_NULL(aSurfaceTransaction);
488 CHECK_NOT_NULL(aSurfaceControl);
chaviwccf3e8b2021-03-25 15:28:44 -0500489 CHECK_VALID_RECT(crop);
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500490
491 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
492 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
493
chaviwccf3e8b2021-03-25 15:28:44 -0500494 transaction->setCrop(surfaceControl, static_cast<const Rect&>(crop));
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500495}
496
chaviwccf3e8b2021-03-25 15:28:44 -0500497void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction,
498 ASurfaceControl* aSurfaceControl, int32_t x, int32_t y) {
499 CHECK_NOT_NULL(aSurfaceTransaction);
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500500 CHECK_NOT_NULL(aSurfaceControl);
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500501
502 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
503 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
504
chaviwccf3e8b2021-03-25 15:28:44 -0500505 transaction->setPosition(surfaceControl, x, y);
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500506}
507
chaviwccf3e8b2021-03-25 15:28:44 -0500508void ASurfaceTransaction_setBufferTransform(ASurfaceTransaction* aSurfaceTransaction,
509 ASurfaceControl* aSurfaceControl, int32_t transform) {
Vasiliy Telezhnikov5ead3aa2021-03-13 19:55:00 -0500510 CHECK_NOT_NULL(aSurfaceTransaction);
511 CHECK_NOT_NULL(aSurfaceControl);
512
513 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
514 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
515
516 transaction->setTransform(surfaceControl, transform);
517 bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
518 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
519 transaction->setTransformToDisplayInverse(surfaceControl, transformToInverseDisplay);
520}
521
chaviwccf3e8b2021-03-25 15:28:44 -0500522void ASurfaceTransaction_setScale(ASurfaceTransaction* aSurfaceTransaction,
523 ASurfaceControl* aSurfaceControl, float xScale, float yScale) {
524 CHECK_NOT_NULL(aSurfaceTransaction);
525 CHECK_NOT_NULL(aSurfaceControl);
526 LOG_ALWAYS_FATAL_IF(xScale < 0, "negative value passed in for xScale");
527 LOG_ALWAYS_FATAL_IF(yScale < 0, "negative value passed in for yScale");
528
529 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
530 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
531
532 transaction->setMatrix(surfaceControl, xScale, 0, 0, yScale);
533}
534
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800535void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
536 ASurfaceControl* aSurfaceControl,
537 int8_t transparency) {
538 CHECK_NOT_NULL(aSurfaceTransaction);
539 CHECK_NOT_NULL(aSurfaceControl);
540
541 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
542 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
543
544 uint32_t flags = (transparency == ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE) ?
545 layer_state_t::eLayerOpaque : 0;
546 transaction->setFlags(surfaceControl, flags, layer_state_t::eLayerOpaque);
547}
548
Marissa Wall1be5a102019-01-18 16:14:04 -0800549void ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* aSurfaceTransaction,
550 ASurfaceControl* aSurfaceControl,
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800551 const ARect rects[], uint32_t count) {
552 CHECK_NOT_NULL(aSurfaceTransaction);
553 CHECK_NOT_NULL(aSurfaceControl);
554
555 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
556 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
557
558 Region region;
559 for (uint32_t i = 0; i < count; ++i) {
Marissa Wallbb9b14f2019-04-23 14:10:15 -0700560 region.orSelf(static_cast<const Rect&>(rects[i]));
561 }
562
563 // Hardware composer interprets a DamageRegion with a single Rect of {0,0,0,0} to be an
564 // undamaged region and {0,0,-1,-1} to be a fully damaged buffer. This is a confusing
565 // distinction for a public api. Instead, default both cases to be a fully damaged buffer.
566 if (count == 1 && region.getBounds().isEmpty()) {
567 transaction->setSurfaceDamageRegion(surfaceControl, Region::INVALID_REGION);
568 return;
Marissa Wallf6a73fa2018-12-10 10:41:08 -0800569 }
570
571 transaction->setSurfaceDamageRegion(surfaceControl, region);
572}
Marissa Wall1be5a102019-01-18 16:14:04 -0800573
574void ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* aSurfaceTransaction,
575 int64_t desiredPresentTime) {
576 CHECK_NOT_NULL(aSurfaceTransaction);
577
578 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
579
580 transaction->setDesiredPresentTime(static_cast<nsecs_t>(desiredPresentTime));
581}
582
583void ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* aSurfaceTransaction,
584 ASurfaceControl* aSurfaceControl,
585 float alpha) {
586 CHECK_NOT_NULL(aSurfaceTransaction);
587 CHECK_NOT_NULL(aSurfaceControl);
588
589 LOG_ALWAYS_FATAL_IF(alpha < 0.0 || alpha > 1.0, "invalid alpha");
590
591 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
592 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
593
594 transaction->setAlpha(surfaceControl, alpha);
595}
596
Marissa Wall7f24f792019-02-07 14:06:04 -0800597void ASurfaceTransaction_setBufferDataSpace(ASurfaceTransaction* aSurfaceTransaction,
598 ASurfaceControl* aSurfaceControl,
599 ADataSpace aDataSpace) {
600 CHECK_NOT_NULL(aSurfaceTransaction);
601 CHECK_NOT_NULL(aSurfaceControl);
602
603 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Valerie Hau5e18c432019-08-26 12:48:49 -0700604 if (!isDataSpaceValid(surfaceControl, aDataSpace)) {
605 ALOGE("Failed to set buffer dataspace - invalid dataspace");
606 return;
607 }
Marissa Wall7f24f792019-02-07 14:06:04 -0800608 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
Marissa Wall7f24f792019-02-07 14:06:04 -0800609 transaction->setDataspace(surfaceControl, static_cast<ui::Dataspace>(aDataSpace));
610}
611
Marissa Wall1be5a102019-01-18 16:14:04 -0800612void ASurfaceTransaction_setHdrMetadata_smpte2086(ASurfaceTransaction* aSurfaceTransaction,
613 ASurfaceControl* aSurfaceControl,
614 struct AHdrMetadata_smpte2086* metadata) {
615 CHECK_NOT_NULL(aSurfaceTransaction);
616 CHECK_NOT_NULL(aSurfaceControl);
617
618 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
619 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
620
621 HdrMetadata hdrMetadata;
622
623 if (metadata) {
624 hdrMetadata.smpte2086.displayPrimaryRed.x = metadata->displayPrimaryRed.x;
625 hdrMetadata.smpte2086.displayPrimaryRed.y = metadata->displayPrimaryRed.y;
626 hdrMetadata.smpte2086.displayPrimaryGreen.x = metadata->displayPrimaryGreen.x;
627 hdrMetadata.smpte2086.displayPrimaryGreen.y = metadata->displayPrimaryGreen.y;
628 hdrMetadata.smpte2086.displayPrimaryBlue.x = metadata->displayPrimaryBlue.x;
629 hdrMetadata.smpte2086.displayPrimaryBlue.y = metadata->displayPrimaryBlue.y;
630 hdrMetadata.smpte2086.whitePoint.x = metadata->whitePoint.x;
631 hdrMetadata.smpte2086.whitePoint.y = metadata->whitePoint.y;
632 hdrMetadata.smpte2086.minLuminance = metadata->minLuminance;
633 hdrMetadata.smpte2086.maxLuminance = metadata->maxLuminance;
634
635 hdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
636 } else {
637 hdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086;
638 }
639
640 transaction->setHdrMetadata(surfaceControl, hdrMetadata);
641}
642
643void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* aSurfaceTransaction,
644 ASurfaceControl* aSurfaceControl,
645 struct AHdrMetadata_cta861_3* metadata) {
646 CHECK_NOT_NULL(aSurfaceTransaction);
647 CHECK_NOT_NULL(aSurfaceControl);
648
649 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
650 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
651
652 HdrMetadata hdrMetadata;
653
654 if (metadata) {
655 hdrMetadata.cta8613.maxContentLightLevel = metadata->maxContentLightLevel;
656 hdrMetadata.cta8613.maxFrameAverageLightLevel = metadata->maxFrameAverageLightLevel;
657
658 hdrMetadata.validTypes |= HdrMetadata::CTA861_3;
659 } else {
660 hdrMetadata.validTypes &= ~HdrMetadata::CTA861_3;
661 }
662
663 transaction->setHdrMetadata(surfaceControl, hdrMetadata);
664}
Valerie Hau5bbfd512019-01-22 17:39:43 -0800665
666void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
667 ASurfaceControl* aSurfaceControl,
668 float r, float g, float b, float alpha,
669 ADataSpace dataspace) {
670 CHECK_NOT_NULL(aSurfaceTransaction);
671 CHECK_NOT_NULL(aSurfaceControl);
672
673 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Valerie Hau5e18c432019-08-26 12:48:49 -0700674 if (!isDataSpaceValid(surfaceControl, dataspace)) {
675 ALOGE("Failed to set buffer dataspace - invalid dataspace");
676 return;
677 }
Valerie Hau5bbfd512019-01-22 17:39:43 -0800678 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
679
680 half3 color;
681 color.r = r;
682 color.g = g;
683 color.b = b;
684
Marin Shalamanov511f9142021-03-16 18:03:30 +0100685 transaction->setBackgroundColor(surfaceControl, color, alpha,
686 static_cast<ui::Dataspace>(dataspace));
Valerie Hau5bbfd512019-01-22 17:39:43 -0800687}
Steven Thomas6cf051e2020-01-14 11:37:21 -0800688
689void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* aSurfaceTransaction,
Steven Thomasdd7bf2f2020-01-31 18:50:02 -0800690 ASurfaceControl* aSurfaceControl, float frameRate,
691 int8_t compatibility) {
Marin Shalamanov511f9142021-03-16 18:03:30 +0100692 ASurfaceTransaction_setFrameRateWithChangeStrategy(
693 aSurfaceTransaction, aSurfaceControl, frameRate, compatibility,
694 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
Marin Shalamanov41ffa8d2020-10-13 12:35:20 +0200695}
696
Marin Shalamanov511f9142021-03-16 18:03:30 +0100697void ASurfaceTransaction_setFrameRateWithChangeStrategy(ASurfaceTransaction* aSurfaceTransaction,
698 ASurfaceControl* aSurfaceControl,
699 float frameRate, int8_t compatibility,
700 int8_t changeFrameRateStrategy) {
Steven Thomas6cf051e2020-01-14 11:37:21 -0800701 CHECK_NOT_NULL(aSurfaceTransaction);
702 CHECK_NOT_NULL(aSurfaceControl);
Steven Thomas6cf051e2020-01-14 11:37:21 -0800703 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
Steven Thomasdd7bf2f2020-01-31 18:50:02 -0800704 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Marin Shalamanov511f9142021-03-16 18:03:30 +0100705 transaction->setFrameRate(surfaceControl, frameRate, compatibility, changeFrameRateStrategy);
Steven Thomas6cf051e2020-01-14 11:37:21 -0800706}
Robert Carrf57c0162021-03-24 15:48:25 -0700707
708void ASurfaceTransaction_setEnableBackPressure(ASurfaceTransaction* aSurfaceTransaction,
709 ASurfaceControl* aSurfaceControl,
710 bool enableBackpressure) {
711 CHECK_NOT_NULL(aSurfaceControl);
712 CHECK_NOT_NULL(aSurfaceTransaction);
713
714 sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
715 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
716
717 const uint32_t flags = enableBackpressure ?
718 layer_state_t::eEnableBackpressure : 0;
719 transaction->setFlags(surfaceControl, flags, layer_state_t::eEnableBackpressure);
720}
Vishnu Nairbeb3b482021-04-21 08:31:27 -0700721
722void ASurfaceTransaction_setOnCommit(ASurfaceTransaction* aSurfaceTransaction, void* context,
723 ASurfaceTransaction_OnCommit func) {
724 CHECK_NOT_NULL(aSurfaceTransaction);
725 CHECK_NOT_NULL(func);
726
727 TransactionCompletedCallbackTakesContext callback =
728 [func](void* callback_context, nsecs_t latchTime, const sp<Fence>& /* presentFence */,
729 const std::vector<SurfaceControlStats>& surfaceControlStats) {
730 ASurfaceTransactionStats aSurfaceTransactionStats;
731 aSurfaceTransactionStats.latchTime = latchTime;
732 aSurfaceTransactionStats.transactionCompleted = false;
733
734 auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
735 for (const auto&
736 [surfaceControl, latchTime, acquireTime, presentFence,
737 previousReleaseFence, transformHint,
738 frameEvents] : surfaceControlStats) {
739 ASurfaceControl* aSurfaceControl =
740 reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
741 aSurfaceControlStats[aSurfaceControl].acquireTime = acquireTime;
742 }
743
744 (*func)(callback_context, &aSurfaceTransactionStats);
745 };
746
747 Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
748
749 transaction->addTransactionCommittedCallback(callback, context);
750}