1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/gl/android/android_surface_control_compat.h"
6 
7 #include <dlfcn.h>
8 #include <android/data_space.h>
9 
10 #include "base/android/build_info.h"
11 #include "base/atomic_sequence_num.h"
12 #include "base/bind.h"
13 #include "base/debug/crash_logging.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/no_destructor.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/system/sys_info.h"
18 #include "base/trace_event/trace_event.h"
19 #include "ui/gfx/color_space.h"
20 
21 extern "C" {
22 typedef struct ASurfaceTransactionStats ASurfaceTransactionStats;
23 typedef void (*ASurfaceTransaction_OnComplete)(void* context,
24                                                ASurfaceTransactionStats* stats);
25 
26 // ASurface
27 using pASurfaceControl_createFromWindow =
28     ASurfaceControl* (*)(ANativeWindow* parent, const char* name);
29 using pASurfaceControl_create = ASurfaceControl* (*)(ASurfaceControl* parent,
30                                                      const char* name);
31 using pASurfaceControl_release = void (*)(ASurfaceControl*);
32 
33 // ASurfaceTransaction enums
34 enum {
35   ASURFACE_TRANSACTION_TRANSPARENCY_TRANSPARENT = 0,
36   ASURFACE_TRANSACTION_TRANSPARENCY_TRANSLUCENT = 1,
37   ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE = 2,
38 };
39 
40 // ASurfaceTransaction
41 using pASurfaceTransaction_create = ASurfaceTransaction* (*)(void);
42 using pASurfaceTransaction_delete = void (*)(ASurfaceTransaction*);
43 using pASurfaceTransaction_apply = int64_t (*)(ASurfaceTransaction*);
44 using pASurfaceTransaction_setOnComplete =
45     void (*)(ASurfaceTransaction*, void* ctx, ASurfaceTransaction_OnComplete);
46 using pASurfaceTransaction_reparent = void (*)(ASurfaceTransaction*,
47                                                ASurfaceControl* surface_control,
48                                                ASurfaceControl* new_parent);
49 using pASurfaceTransaction_setVisibility = void (*)(ASurfaceTransaction*,
50                                                     ASurfaceControl*,
51                                                     int8_t visibility);
52 using pASurfaceTransaction_setZOrder =
53     void (*)(ASurfaceTransaction* transaction, ASurfaceControl*, int32_t z);
54 using pASurfaceTransaction_setBuffer =
55     void (*)(ASurfaceTransaction* transaction,
56              ASurfaceControl*,
57              AHardwareBuffer*,
58              int32_t fence_fd);
59 using pASurfaceTransaction_setGeometry =
60     void (*)(ASurfaceTransaction* transaction,
61              ASurfaceControl* surface,
62              const ARect& src,
63              const ARect& dst,
64              int32_t transform);
65 using pASurfaceTransaction_setBufferTransparency =
66     void (*)(ASurfaceTransaction* transaction,
67              ASurfaceControl* surface,
68              int8_t transparency);
69 using pASurfaceTransaction_setDamageRegion =
70     void (*)(ASurfaceTransaction* transaction,
71              ASurfaceControl* surface,
72              const ARect rects[],
73              uint32_t count);
74 using pASurfaceTransaction_setBufferDataSpace =
75     void (*)(ASurfaceTransaction* transaction,
76              ASurfaceControl* surface,
77              uint64_t data_space);
78 
79 // ASurfaceTransactionStats
80 using pASurfaceTransactionStats_getPresentFenceFd =
81     int (*)(ASurfaceTransactionStats* stats);
82 using pASurfaceTransactionStats_getLatchTime =
83     int64_t (*)(ASurfaceTransactionStats* stats);
84 using pASurfaceTransactionStats_getASurfaceControls =
85     void (*)(ASurfaceTransactionStats* stats,
86              ASurfaceControl*** surface_controls,
87              size_t* size);
88 using pASurfaceTransactionStats_releaseASurfaceControls =
89     void (*)(ASurfaceControl** surface_controls);
90 using pASurfaceTransactionStats_getPreviousReleaseFenceFd =
91     int (*)(ASurfaceTransactionStats* stats, ASurfaceControl* surface_control);
92 }
93 
94 namespace gl {
95 namespace {
96 
97 base::AtomicSequenceNumber g_next_transaction_id;
98 
99 uint64_t g_agb_required_usage_bits = AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY;
100 
101 #define LOAD_FUNCTION(lib, func)                             \
102   do {                                                       \
103     func##Fn = reinterpret_cast<p##func>(dlsym(lib, #func)); \
104     if (!func##Fn) {                                         \
105       supported = false;                                     \
106       LOG(ERROR) << "Unable to load function " << #func;     \
107     }                                                        \
108   } while (0)
109 
110 struct SurfaceControlMethods {
111  public:
Getgl::__anone42c85bf0211::SurfaceControlMethods112   static const SurfaceControlMethods& Get() {
113     static const base::NoDestructor<SurfaceControlMethods> instance;
114     return *instance;
115   }
116 
SurfaceControlMethodsgl::__anone42c85bf0211::SurfaceControlMethods117   SurfaceControlMethods() {
118     void* main_dl_handle = dlopen("libandroid.so", RTLD_NOW);
119     if (!main_dl_handle) {
120       LOG(ERROR) << "Couldnt load android so";
121       supported = false;
122       return;
123     }
124 
125     LOAD_FUNCTION(main_dl_handle, ASurfaceControl_createFromWindow);
126     LOAD_FUNCTION(main_dl_handle, ASurfaceControl_create);
127     LOAD_FUNCTION(main_dl_handle, ASurfaceControl_release);
128 
129     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_create);
130     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_delete);
131     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_apply);
132     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setOnComplete);
133     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_reparent);
134     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setVisibility);
135     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setZOrder);
136     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setBuffer);
137     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setGeometry);
138     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setBufferTransparency);
139     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setDamageRegion);
140     LOAD_FUNCTION(main_dl_handle, ASurfaceTransaction_setBufferDataSpace);
141 
142     LOAD_FUNCTION(main_dl_handle, ASurfaceTransactionStats_getPresentFenceFd);
143     LOAD_FUNCTION(main_dl_handle, ASurfaceTransactionStats_getLatchTime);
144     LOAD_FUNCTION(main_dl_handle, ASurfaceTransactionStats_getASurfaceControls);
145     LOAD_FUNCTION(main_dl_handle,
146                   ASurfaceTransactionStats_releaseASurfaceControls);
147     LOAD_FUNCTION(main_dl_handle,
148                   ASurfaceTransactionStats_getPreviousReleaseFenceFd);
149   }
150 
151   ~SurfaceControlMethods() = default;
152 
153   bool supported = true;
154   // Surface methods.
155   pASurfaceControl_createFromWindow ASurfaceControl_createFromWindowFn;
156   pASurfaceControl_create ASurfaceControl_createFn;
157   pASurfaceControl_release ASurfaceControl_releaseFn;
158 
159   // Transaction methods.
160   pASurfaceTransaction_create ASurfaceTransaction_createFn;
161   pASurfaceTransaction_delete ASurfaceTransaction_deleteFn;
162   pASurfaceTransaction_apply ASurfaceTransaction_applyFn;
163   pASurfaceTransaction_setOnComplete ASurfaceTransaction_setOnCompleteFn;
164   pASurfaceTransaction_reparent ASurfaceTransaction_reparentFn;
165   pASurfaceTransaction_setVisibility ASurfaceTransaction_setVisibilityFn;
166   pASurfaceTransaction_setZOrder ASurfaceTransaction_setZOrderFn;
167   pASurfaceTransaction_setBuffer ASurfaceTransaction_setBufferFn;
168   pASurfaceTransaction_setGeometry ASurfaceTransaction_setGeometryFn;
169   pASurfaceTransaction_setBufferTransparency
170       ASurfaceTransaction_setBufferTransparencyFn;
171   pASurfaceTransaction_setDamageRegion ASurfaceTransaction_setDamageRegionFn;
172   pASurfaceTransaction_setBufferDataSpace
173       ASurfaceTransaction_setBufferDataSpaceFn;
174 
175   // TransactionStats methods.
176   pASurfaceTransactionStats_getPresentFenceFd
177       ASurfaceTransactionStats_getPresentFenceFdFn;
178   pASurfaceTransactionStats_getLatchTime
179       ASurfaceTransactionStats_getLatchTimeFn;
180   pASurfaceTransactionStats_getASurfaceControls
181       ASurfaceTransactionStats_getASurfaceControlsFn;
182   pASurfaceTransactionStats_releaseASurfaceControls
183       ASurfaceTransactionStats_releaseASurfaceControlsFn;
184   pASurfaceTransactionStats_getPreviousReleaseFenceFd
185       ASurfaceTransactionStats_getPreviousReleaseFenceFdFn;
186 };
187 
RectToARect(const gfx::Rect & rect)188 ARect RectToARect(const gfx::Rect& rect) {
189   return ARect{rect.x(), rect.y(), rect.right(), rect.bottom()};
190 }
191 
OverlayTransformToWindowTransform(gfx::OverlayTransform transform)192 int32_t OverlayTransformToWindowTransform(gfx::OverlayTransform transform) {
193   // Note that the gfx::OverlayTransform expresses rotations in anticlockwise
194   // direction while the ANativeWindow rotations are in clockwise direction.
195   switch (transform) {
196     case gfx::OVERLAY_TRANSFORM_INVALID:
197       DCHECK(false) << "Invalid Transform";
198       return ANATIVEWINDOW_TRANSFORM_IDENTITY;
199     case gfx::OVERLAY_TRANSFORM_NONE:
200       return ANATIVEWINDOW_TRANSFORM_IDENTITY;
201     case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
202       return ANATIVEWINDOW_TRANSFORM_MIRROR_HORIZONTAL;
203     case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
204       return ANATIVEWINDOW_TRANSFORM_MIRROR_VERTICAL;
205     case gfx::OVERLAY_TRANSFORM_ROTATE_90:
206       return ANATIVEWINDOW_TRANSFORM_ROTATE_270;
207     case gfx::OVERLAY_TRANSFORM_ROTATE_180:
208       return ANATIVEWINDOW_TRANSFORM_ROTATE_180;
209     case gfx::OVERLAY_TRANSFORM_ROTATE_270:
210       return ANATIVEWINDOW_TRANSFORM_ROTATE_90;
211   };
212   NOTREACHED();
213   return ANATIVEWINDOW_TRANSFORM_IDENTITY;
214 }
215 
ColorSpaceToADataSpace(const gfx::ColorSpace & color_space)216 uint64_t ColorSpaceToADataSpace(const gfx::ColorSpace& color_space) {
217   if (!color_space.IsValid() || color_space == gfx::ColorSpace::CreateSRGB())
218     return ADATASPACE_SRGB;
219 
220   if (color_space == gfx::ColorSpace::CreateSCRGBLinear())
221     return ADATASPACE_SCRGB_LINEAR;
222 
223   if (color_space == gfx::ColorSpace::CreateDisplayP3D65())
224     return ADATASPACE_DISPLAY_P3;
225 
226   // TODO(khushalsagar): Check if we can support BT2020 using
227   // ADATASPACE_BT2020_PQ.
228   return ADATASPACE_UNKNOWN;
229 }
230 
ToTransactionStats(ASurfaceTransactionStats * stats)231 SurfaceControl::TransactionStats ToTransactionStats(
232     ASurfaceTransactionStats* stats) {
233   SurfaceControl::TransactionStats transaction_stats;
234   transaction_stats.present_fence = base::ScopedFD(
235       SurfaceControlMethods::Get().ASurfaceTransactionStats_getPresentFenceFdFn(
236           stats));
237   transaction_stats.latch_time =
238       base::TimeTicks() +
239       base::TimeDelta::FromNanoseconds(
240           SurfaceControlMethods::Get().ASurfaceTransactionStats_getLatchTimeFn(
241               stats));
242   if (transaction_stats.latch_time == base::TimeTicks())
243     transaction_stats.latch_time = base::TimeTicks::Now();
244 
245   ASurfaceControl** surface_controls = nullptr;
246   size_t size = 0u;
247   SurfaceControlMethods::Get().ASurfaceTransactionStats_getASurfaceControlsFn(
248       stats, &surface_controls, &size);
249   transaction_stats.surface_stats.resize(size);
250   for (size_t i = 0u; i < size; ++i) {
251     transaction_stats.surface_stats[i].surface = surface_controls[i];
252     int fence_fd = SurfaceControlMethods::Get()
253                        .ASurfaceTransactionStats_getPreviousReleaseFenceFdFn(
254                            stats, surface_controls[i]);
255     if (fence_fd != -1) {
256       transaction_stats.surface_stats[i].fence = base::ScopedFD(fence_fd);
257     }
258   }
259   SurfaceControlMethods::Get()
260       .ASurfaceTransactionStats_releaseASurfaceControlsFn(surface_controls);
261 
262   return transaction_stats;
263 }
264 
265 struct TransactionAckCtx {
266   int id = 0;
267   scoped_refptr<base::SingleThreadTaskRunner> task_runner;
268   SurfaceControl::Transaction::OnCompleteCb callback;
269 };
270 
271 // Note that the framework API states that this callback can be dispatched on
272 // any thread (in practice it should be the binder thread).
OnTransactionCompletedOnAnyThread(void * context,ASurfaceTransactionStats * stats)273 void OnTransactionCompletedOnAnyThread(void* context,
274                                        ASurfaceTransactionStats* stats) {
275   auto* ack_ctx = static_cast<TransactionAckCtx*>(context);
276   auto transaction_stats = ToTransactionStats(stats);
277   TRACE_EVENT_ASYNC_END0("gpu,benchmark", "SurfaceControlTransaction",
278                          ack_ctx->id);
279 
280   if (ack_ctx->task_runner) {
281     ack_ctx->task_runner->PostTask(
282         FROM_HERE, base::BindOnce(std::move(ack_ctx->callback),
283                                   std::move(transaction_stats)));
284   } else {
285     std::move(ack_ctx->callback).Run(std::move(transaction_stats));
286   }
287 
288   delete ack_ctx;
289 }
290 }  // namespace
291 
292 // static
IsSupported()293 bool SurfaceControl::IsSupported() {
294   if (!base::android::BuildInfo::GetInstance()->is_at_least_q())
295     return false;
296 
297   CHECK(SurfaceControlMethods::Get().supported);
298   return true;
299 }
300 
SupportsColorSpace(const gfx::ColorSpace & color_space)301 bool SurfaceControl::SupportsColorSpace(const gfx::ColorSpace& color_space) {
302   return ColorSpaceToADataSpace(color_space) != ADATASPACE_UNKNOWN;
303 }
304 
RequiredUsage()305 uint64_t SurfaceControl::RequiredUsage() {
306   if (!IsSupported())
307     return 0u;
308   return g_agb_required_usage_bits;
309 }
310 
EnableQualcommUBWC()311 void SurfaceControl::EnableQualcommUBWC() {
312   g_agb_required_usage_bits |= AHARDWAREBUFFER_USAGE_VENDOR_0;
313 }
314 
315 SurfaceControl::Surface::Surface() = default;
316 
Surface(const Surface & parent,const char * name)317 SurfaceControl::Surface::Surface(const Surface& parent, const char* name) {
318   surface_ = SurfaceControlMethods::Get().ASurfaceControl_createFn(
319       parent.surface(), name);
320   if (!surface_)
321     LOG(ERROR) << "Failed to create ASurfaceControl : " << name;
322 }
323 
Surface(ANativeWindow * parent,const char * name)324 SurfaceControl::Surface::Surface(ANativeWindow* parent, const char* name) {
325   surface_ = SurfaceControlMethods::Get().ASurfaceControl_createFromWindowFn(
326       parent, name);
327   if (!surface_)
328     LOG(ERROR) << "Failed to create ASurfaceControl : " << name;
329 }
330 
~Surface()331 SurfaceControl::Surface::~Surface() {
332   if (surface_) {
333     // It is important to detach the surface from the tree before deleting it.
334     Transaction transaction;
335     transaction.SetParent(*this, nullptr);
336     transaction.Apply();
337 
338     SurfaceControlMethods::Get().ASurfaceControl_releaseFn(surface_);
339   }
340 }
341 
342 SurfaceControl::SurfaceStats::SurfaceStats() = default;
343 SurfaceControl::SurfaceStats::~SurfaceStats() = default;
344 
345 SurfaceControl::SurfaceStats::SurfaceStats(SurfaceStats&& other) = default;
346 SurfaceControl::SurfaceStats& SurfaceControl::SurfaceStats::operator=(
347     SurfaceStats&& other) = default;
348 
349 SurfaceControl::TransactionStats::TransactionStats() = default;
350 SurfaceControl::TransactionStats::~TransactionStats() = default;
351 
352 SurfaceControl::TransactionStats::TransactionStats(TransactionStats&& other) =
353     default;
354 SurfaceControl::TransactionStats& SurfaceControl::TransactionStats::operator=(
355     TransactionStats&& other) = default;
356 
Transaction()357 SurfaceControl::Transaction::Transaction()
358     : id_(g_next_transaction_id.GetNext()) {
359   transaction_ = SurfaceControlMethods::Get().ASurfaceTransaction_createFn();
360   DCHECK(transaction_);
361 }
362 
~Transaction()363 SurfaceControl::Transaction::~Transaction() {
364   if (transaction_)
365     SurfaceControlMethods::Get().ASurfaceTransaction_deleteFn(transaction_);
366 }
367 
Transaction(Transaction && other)368 SurfaceControl::Transaction::Transaction(Transaction&& other)
369     : id_(other.id_), transaction_(other.transaction_) {
370   other.transaction_ = nullptr;
371   other.id_ = 0;
372 }
373 
operator =(Transaction && other)374 SurfaceControl::Transaction& SurfaceControl::Transaction::operator=(
375     Transaction&& other) {
376   if (transaction_)
377     SurfaceControlMethods::Get().ASurfaceTransaction_deleteFn(transaction_);
378 
379   transaction_ = other.transaction_;
380   id_ = other.id_;
381 
382   other.transaction_ = nullptr;
383   other.id_ = 0;
384   return *this;
385 }
386 
SetVisibility(const Surface & surface,bool show)387 void SurfaceControl::Transaction::SetVisibility(const Surface& surface,
388                                                 bool show) {
389   SurfaceControlMethods::Get().ASurfaceTransaction_setVisibilityFn(
390       transaction_, surface.surface(), show);
391 }
392 
SetZOrder(const Surface & surface,int32_t z)393 void SurfaceControl::Transaction::SetZOrder(const Surface& surface, int32_t z) {
394   SurfaceControlMethods::Get().ASurfaceTransaction_setZOrderFn(
395       transaction_, surface.surface(), z);
396 }
397 
SetBuffer(const Surface & surface,AHardwareBuffer * buffer,base::ScopedFD fence_fd)398 void SurfaceControl::Transaction::SetBuffer(const Surface& surface,
399                                             AHardwareBuffer* buffer,
400                                             base::ScopedFD fence_fd) {
401   SurfaceControlMethods::Get().ASurfaceTransaction_setBufferFn(
402       transaction_, surface.surface(), buffer,
403       fence_fd.is_valid() ? fence_fd.release() : -1);
404 }
405 
SetGeometry(const Surface & surface,const gfx::Rect & src,const gfx::Rect & dst,gfx::OverlayTransform transform)406 void SurfaceControl::Transaction::SetGeometry(const Surface& surface,
407                                               const gfx::Rect& src,
408                                               const gfx::Rect& dst,
409                                               gfx::OverlayTransform transform) {
410   SurfaceControlMethods::Get().ASurfaceTransaction_setGeometryFn(
411       transaction_, surface.surface(), RectToARect(src), RectToARect(dst),
412       OverlayTransformToWindowTransform(transform));
413 }
414 
SetOpaque(const Surface & surface,bool opaque)415 void SurfaceControl::Transaction::SetOpaque(const Surface& surface,
416                                             bool opaque) {
417   int8_t transparency = opaque ? ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE
418                                : ASURFACE_TRANSACTION_TRANSPARENCY_TRANSLUCENT;
419   SurfaceControlMethods::Get().ASurfaceTransaction_setBufferTransparencyFn(
420       transaction_, surface.surface(), transparency);
421 }
422 
SetDamageRect(const Surface & surface,const gfx::Rect & rect)423 void SurfaceControl::Transaction::SetDamageRect(const Surface& surface,
424                                                 const gfx::Rect& rect) {
425   auto a_rect = RectToARect(rect);
426   SurfaceControlMethods::Get().ASurfaceTransaction_setDamageRegionFn(
427       transaction_, surface.surface(), &a_rect, 1u);
428 }
429 
SetColorSpace(const Surface & surface,const gfx::ColorSpace & color_space)430 void SurfaceControl::Transaction::SetColorSpace(
431     const Surface& surface,
432     const gfx::ColorSpace& color_space) {
433   auto data_space = ColorSpaceToADataSpace(color_space);
434 
435   // Log the data space in crash keys for debugging crbug.com/997592.
436   static auto* kCrashKey = base::debug::AllocateCrashKeyString(
437       "data_space_for_buffer", base::debug::CrashKeySize::Size256);
438   auto crash_key_value = base::NumberToString(data_space);
439   base::debug::ScopedCrashKeyString scoped_crash_key(kCrashKey,
440                                                      crash_key_value);
441 
442   SurfaceControlMethods::Get().ASurfaceTransaction_setBufferDataSpaceFn(
443       transaction_, surface.surface(), data_space);
444 }
445 
SetOnCompleteCb(OnCompleteCb cb,scoped_refptr<base::SingleThreadTaskRunner> task_runner)446 void SurfaceControl::Transaction::SetOnCompleteCb(
447     OnCompleteCb cb,
448     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
449   TransactionAckCtx* ack_ctx = new TransactionAckCtx;
450   ack_ctx->callback = std::move(cb);
451   ack_ctx->task_runner = std::move(task_runner);
452   ack_ctx->id = id_;
453 
454   SurfaceControlMethods::Get().ASurfaceTransaction_setOnCompleteFn(
455       transaction_, ack_ctx, &OnTransactionCompletedOnAnyThread);
456 }
457 
SetParent(const Surface & surface,const Surface * new_parent)458 void SurfaceControl::Transaction::SetParent(const Surface& surface,
459                                             const Surface* new_parent) {
460   SurfaceControlMethods::Get().ASurfaceTransaction_reparentFn(
461       transaction_, surface.surface(),
462       new_parent ? new_parent->surface() : nullptr);
463 }
464 
Apply()465 void SurfaceControl::Transaction::Apply() {
466   TRACE_EVENT_ASYNC_BEGIN0("gpu,benchmark", "SurfaceControlTransaction", id_);
467   SurfaceControlMethods::Get().ASurfaceTransaction_applyFn(transaction_);
468 }
469 
470 }  // namespace gl
471