OSDN Git Service

Weston: Upload only damaged region.
[android-x86/external-IA-Hardware-Composer.git] / os / linux / linux_frontend.cpp
1 /*
2  * Copyright (c) 2017 Intel Corporation
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
17 #include "linux_frontend.h"
18 #include <commondrmutils.h>
19 #include <hwcrect.h>
20
21 #include "nativebufferhandler.h"
22
23 #include "pixeluploader.h"
24
25 namespace hwcomposer {
26
27 class IAHWCVsyncCallback : public hwcomposer::VsyncCallback {
28  public:
29   IAHWCVsyncCallback(iahwc_callback_data_t data, iahwc_function_ptr_t hook)
30       : data_(data), hook_(hook) {
31   }
32
33   void Callback(uint32_t display, int64_t timestamp) {
34     if (hook_ != NULL) {
35       auto hook = reinterpret_cast<IAHWC_PFN_VSYNC>(hook_);
36       hook(data_, display, timestamp);
37     }
38   }
39
40  private:
41   iahwc_callback_data_t data_;
42   iahwc_function_ptr_t hook_;
43 };
44
45 class IAPixelUploaderCallback : public hwcomposer::RawPixelUploadCallback {
46  public:
47   IAPixelUploaderCallback(iahwc_callback_data_t data, iahwc_function_ptr_t hook,
48                           uint32_t display_id)
49       : data_(data), hook_(hook), display_(display_id) {
50   }
51
52   void Callback(bool start_access, void* call_back_data) {
53     if (hook_ != NULL) {
54       auto hook = reinterpret_cast<IAHWC_PFN_PIXEL_UPLOADER>(hook_);
55       hook(data_, display_, start_access ? 1 : 0, call_back_data);
56     }
57   }
58
59  private:
60   iahwc_callback_data_t data_;
61   iahwc_function_ptr_t hook_;
62   uint32_t display_;
63 };
64
65 class IAHWCHotPlugEventCallback : public hwcomposer::HotPlugCallback {
66  public:
67   IAHWCHotPlugEventCallback(iahwc_callback_data_t data,
68                          iahwc_function_ptr_t hook,
69                          IAHWC::IAHWCDisplay *display)
70       : data_(data), hook_(hook), display_(display) {
71   }
72
73   void Callback(uint32_t display, bool connected) {
74
75     auto hook = reinterpret_cast<IAHWC_PFN_HOTPLUG>(hook_);
76     uint32_t status;
77     if (connected) {
78       status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_CONNECTED);
79       if (display_)
80         display_->RunPixelUploader(true);
81     } else {
82       status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_DISCONNECTED);
83       if (display_)
84         display_->RunPixelUploader(false);
85     }
86
87     if (hook)
88       hook(data_, display, status);
89
90   }
91
92  private:
93   iahwc_callback_data_t data_;
94   iahwc_function_ptr_t hook_;
95   IAHWC::IAHWCDisplay *display_;
96 };
97
98 IAHWC::IAHWC() {
99   getFunctionPtr = HookGetFunctionPtr;
100   close = HookClose;
101 }
102
103 int32_t IAHWC::Init() {
104   if (!device_.Initialize()) {
105     fprintf(stderr, "Unable to initialize GPU DEVICE");
106     return IAHWC_ERROR_NO_RESOURCES;
107   }
108
109   std::vector<hwcomposer::NativeDisplay*> displays = device_.GetAllDisplays();
110
111   for (hwcomposer::NativeDisplay* display : displays) {
112     displays_.emplace_back(new IAHWCDisplay());
113     IAHWCDisplay* iahwc_display = displays_.back();
114     iahwc_display->Init(display, device_.GetFD());
115   }
116
117   return IAHWC_ERROR_NONE;
118 }
119
120 int IAHWC::HookOpen(const iahwc_module_t* module, iahwc_device_t** device) {
121   IAHWC* iahwc = new IAHWC();
122   iahwc->Init();
123   *device = iahwc;
124
125   return IAHWC_ERROR_NONE;
126 }
127
128 iahwc_function_ptr_t IAHWC::HookGetFunctionPtr(iahwc_device_t* /* device */,
129                                                int func_descriptor) {
130   switch (func_descriptor) {
131     case IAHWC_FUNC_GET_NUM_DISPLAYS:
132       return ToHook<IAHWC_PFN_GET_NUM_DISPLAYS>(
133           DeviceHook<int32_t, decltype(&IAHWC::GetNumDisplays),
134                      &IAHWC::GetNumDisplays, int*>);
135     case IAHWC_FUNC_REGISTER_CALLBACK:
136       return ToHook<IAHWC_PFN_REGISTER_CALLBACK>(
137           DeviceHook<int32_t, decltype(&IAHWC::RegisterCallback),
138                      &IAHWC::RegisterCallback, int, uint32_t,
139                      iahwc_callback_data_t, iahwc_function_ptr_t>);
140     case IAHWC_FUNC_DISPLAY_GET_INFO:
141       return ToHook<IAHWC_PFN_DISPLAY_GET_INFO>(
142           DisplayHook<decltype(&IAHWCDisplay::GetDisplayInfo),
143                       &IAHWCDisplay::GetDisplayInfo, uint32_t, int, int32_t*>);
144     case IAHWC_FUNC_DISPLAY_GET_NAME:
145       return ToHook<IAHWC_PFN_DISPLAY_GET_NAME>(
146           DisplayHook<decltype(&IAHWCDisplay::GetDisplayName),
147                       &IAHWCDisplay::GetDisplayName, uint32_t*, char*>);
148     case IAHWC_FUNC_DISPLAY_GET_CONFIGS:
149       return ToHook<IAHWC_PFN_DISPLAY_GET_CONFIGS>(
150           DisplayHook<decltype(&IAHWCDisplay::GetDisplayConfigs),
151                       &IAHWCDisplay::GetDisplayConfigs, uint32_t*, uint32_t*>);
152     case IAHWC_FUNC_DISPLAY_SET_GAMMA:
153       return ToHook<IAHWC_PFN_DISPLAY_SET_GAMMA>(
154           DisplayHook<decltype(&IAHWCDisplay::SetDisplayGamma),
155                       &IAHWCDisplay::SetDisplayGamma, float, float, float>);
156     case IAHWC_FUNC_DISPLAY_SET_CONFIG:
157       return ToHook<IAHWC_PFN_DISPLAY_SET_CONFIG>(
158           DisplayHook<decltype(&IAHWCDisplay::SetDisplayConfig),
159                       &IAHWCDisplay::SetDisplayConfig, uint32_t>);
160     case IAHWC_FUNC_DISPLAY_GET_CONFIG:
161       return ToHook<IAHWC_PFN_DISPLAY_GET_CONFIG>(
162           DisplayHook<decltype(&IAHWCDisplay::GetDisplayConfig),
163                       &IAHWCDisplay::GetDisplayConfig, uint32_t*>);
164     case IAHWC_FUNC_DISPLAY_CLEAR_ALL_LAYERS:
165       return ToHook<IAHWC_PFN_DISPLAY_CLEAR_ALL_LAYERS>(
166           DisplayHook<decltype(&IAHWCDisplay::ClearAllLayers),
167                       &IAHWCDisplay::ClearAllLayers>);
168     case IAHWC_FUNC_PRESENT_DISPLAY:
169       return ToHook<IAHWC_PFN_PRESENT_DISPLAY>(
170           DisplayHook<decltype(&IAHWCDisplay::PresentDisplay),
171                       &IAHWCDisplay::PresentDisplay, int32_t*>);
172     case IAHWC_FUNC_DISABLE_OVERLAY_USAGE:
173       return ToHook<IAHWC_PFN_DISABLE_OVERLAY_USAGE>(
174           DisplayHook<decltype(&IAHWCDisplay::DisableOverlayUsage),
175                       &IAHWCDisplay::DisableOverlayUsage>);
176     case IAHWC_FUNC_ENABLE_OVERLAY_USAGE:
177       return ToHook<IAHWC_PFN_ENABLE_OVERLAY_USAGE>(
178           DisplayHook<decltype(&IAHWCDisplay::EnableOverlayUsage),
179                       &IAHWCDisplay::EnableOverlayUsage>);
180     case IAHWC_FUNC_CREATE_LAYER:
181       return ToHook<IAHWC_PFN_CREATE_LAYER>(
182           DisplayHook<decltype(&IAHWCDisplay::CreateLayer),
183                       &IAHWCDisplay::CreateLayer, uint32_t*>);
184     case IAHWC_FUNC_DESTROY_LAYER:
185       return ToHook<IAHWC_PFN_DESTROY_LAYER>(
186           DisplayHook<decltype(&IAHWCDisplay::DestroyLayer),
187                       &IAHWCDisplay::DestroyLayer, uint32_t>);
188     case IAHWC_FUNC_LAYER_SET_BO:
189       return ToHook<IAHWC_PFN_LAYER_SET_BO>(
190           LayerHook<decltype(&IAHWCLayer::SetBo), &IAHWCLayer::SetBo, gbm_bo*>);
191     case IAHWC_FUNC_LAYER_SET_RAW_PIXEL_DATA:
192       return ToHook<IAHWC_PFN_LAYER_SET_RAW_PIXEL_DATA>(
193           LayerHook<decltype(&IAHWCLayer::SetRawPixelData),
194                     &IAHWCLayer::SetRawPixelData, iahwc_raw_pixel_data>);
195     case IAHWC_FUNC_LAYER_SET_ACQUIRE_FENCE:
196       return ToHook<IAHWC_PFN_LAYER_SET_ACQUIRE_FENCE>(
197           LayerHook<decltype(&IAHWCLayer::SetAcquireFence),
198                     &IAHWCLayer::SetAcquireFence, int32_t>);
199     case IAHWC_FUNC_LAYER_SET_USAGE:
200       return ToHook<IAHWC_PFN_LAYER_SET_USAGE>(
201           LayerHook<decltype(&IAHWCLayer::SetLayerUsage),
202                     &IAHWCLayer::SetLayerUsage, int32_t>);
203     case IAHWC_FUNC_LAYER_SET_TRANSFORM:
204       return ToHook<IAHWC_PFN_LAYER_SET_TRANSFORM>(
205           LayerHook<decltype(&IAHWCLayer::SetLayerTransform),
206                     &IAHWCLayer::SetLayerTransform, int32_t>);
207     case IAHWC_FUNC_LAYER_SET_SOURCE_CROP:
208       return ToHook<IAHWC_PFN_LAYER_SET_SOURCE_CROP>(
209           LayerHook<decltype(&IAHWCLayer::SetLayerSourceCrop),
210                     &IAHWCLayer::SetLayerSourceCrop, iahwc_rect_t>);
211     case IAHWC_FUNC_LAYER_SET_DISPLAY_FRAME:
212       return ToHook<IAHWC_PFN_LAYER_SET_DISPLAY_FRAME>(
213           LayerHook<decltype(&IAHWCLayer::SetLayerDisplayFrame),
214                     &IAHWCLayer::SetLayerDisplayFrame, iahwc_rect_t>);
215     case IAHWC_FUNC_LAYER_SET_SURFACE_DAMAGE:
216       return ToHook<IAHWC_PFN_LAYER_SET_SURFACE_DAMAGE>(
217           LayerHook<decltype(&IAHWCLayer::SetLayerSurfaceDamage),
218                     &IAHWCLayer::SetLayerSurfaceDamage, iahwc_region_t>);
219     case IAHWC_FUNC_LAYER_SET_PLANE_ALPHA:
220       return ToHook<IAHWC_PFN_LAYER_SET_PLANE_ALPHA>(
221           LayerHook<decltype(&IAHWCLayer::SetLayerPlaneAlpha),
222                     &IAHWCLayer::SetLayerPlaneAlpha, float>);
223     case IAHWC_FUNC_LAYER_SET_INDEX:
224       return ToHook<IAHWC_PFN_LAYER_SET_INDEX>(
225           LayerHook<decltype(&IAHWCLayer::SetLayerIndex),
226                     &IAHWCLayer::SetLayerIndex, uint32_t>);
227     case IAHWC_FUNC_INVALID:
228     default:
229       return NULL;
230   }
231 }
232
233 int IAHWC::HookClose(iahwc_device_t* dev) {
234   delete dev;
235   return 0;
236 }
237
238 // private function implementations
239
240 int IAHWC::GetNumDisplays(int* num_displays) {
241   *num_displays = 0;
242   for (IAHWCDisplay* display : displays_) {
243     if (display->IsConnected())
244       *num_displays += 1;
245   }
246
247   return IAHWC_ERROR_NONE;
248 }
249
250 int IAHWC::RegisterCallback(int32_t description, uint32_t display_id,
251                             iahwc_callback_data_t data,
252                             iahwc_function_ptr_t hook) {
253   switch (description) {
254     case IAHWC_CALLBACK_VSYNC: {
255       if (display_id >= displays_.size())
256         return IAHWC_ERROR_BAD_DISPLAY;
257       IAHWCDisplay* display = displays_.at(display_id);
258       return display->RegisterVsyncCallback(data, hook);
259     }
260     case IAHWC_CALLBACK_PIXEL_UPLOADER: {
261       if (display_id >= displays_.size())
262         return IAHWC_ERROR_BAD_DISPLAY;
263
264       IAHWCDisplay* display = displays_.at(display_id);
265       display->RegisterPixelUploaderCallback(data, hook);
266       return IAHWC_ERROR_NONE;
267     }
268   case IAHWC_CALLBACK_HOTPLUG: {
269     if (display_id >= displays_.size())
270       return IAHWC_ERROR_BAD_DISPLAY;
271     for (auto display : displays_)
272       display->RegisterHotPlugCallback(data, hook);
273     return IAHWC_ERROR_NONE;
274   }
275
276     default:
277       return IAHWC_ERROR_BAD_PARAMETER;
278   }
279 }
280
281 IAHWC::IAHWCDisplay::IAHWCDisplay() : native_display_(NULL) {
282 }
283
284 IAHWC::IAHWCDisplay::~IAHWCDisplay() {
285   delete raw_data_uploader_;
286 }
287
288 int IAHWC::IAHWCDisplay::Init(hwcomposer::NativeDisplay* display,
289                               uint32_t gpu_fd) {
290   native_display_ = display;
291   native_display_->InitializeLayerHashGenerator(4);
292   raw_data_uploader_ =
293       new PixelUploader(native_display_->GetNativeBufferHandler());
294 }
295
296 int IAHWC::IAHWCDisplay::GetDisplayInfo(uint32_t config, int attribute,
297                                         int32_t* value) {
298   hwcomposer::HWCDisplayAttribute attrib =
299       static_cast<hwcomposer::HWCDisplayAttribute>(attribute);
300
301   bool ret = native_display_->GetDisplayAttribute(config, attrib, value);
302
303   if (!ret)
304     return IAHWC_ERROR_NO_RESOURCES;
305
306   return IAHWC_ERROR_NONE;
307 }
308
309 int IAHWC::IAHWCDisplay::GetDisplayName(uint32_t* size, char* name) {
310   bool ret = native_display_->GetDisplayName(size, name);
311
312   if (!ret)
313     return IAHWC_ERROR_NO_RESOURCES;
314
315   return IAHWC_ERROR_NONE;
316 }
317
318 int IAHWC::IAHWCDisplay::GetDisplayConfigs(uint32_t* num_configs,
319                                            uint32_t* configs) {
320   bool ret = native_display_->GetDisplayConfigs(num_configs, configs);
321
322   if (!ret)
323     return IAHWC_ERROR_NO_RESOURCES;
324
325   return IAHWC_ERROR_NONE;
326 }
327
328 int IAHWC::IAHWCDisplay::SetDisplayGamma(float r, float b, float g) {
329   native_display_->SetGamma(r, g, b);
330   return IAHWC_ERROR_NONE;
331 }
332
333 int IAHWC::IAHWCDisplay::SetDisplayConfig(uint32_t config) {
334   bool ret = native_display_->SetActiveConfig(config);
335
336   if (!ret)
337     return IAHWC_ERROR_NO_RESOURCES;
338
339   return IAHWC_ERROR_NONE;
340 }
341
342 int IAHWC::IAHWCDisplay::GetDisplayConfig(uint32_t* config) {
343   bool ret = native_display_->GetActiveConfig(config);
344
345   if (!ret)
346     return IAHWC_ERROR_NO_RESOURCES;
347
348   return IAHWC_ERROR_NONE;
349 }
350
351 int IAHWC::IAHWCDisplay::ClearAllLayers() {
352   layers_.clear();
353   native_display_->ResetLayerHashGenerator();
354
355   return IAHWC_ERROR_NONE;
356 }
357 int IAHWC::IAHWCDisplay::PresentDisplay(int32_t* release_fd) {
358   std::vector<hwcomposer::HwcLayer*> layers;
359   /*
360    * Here the assumption is that the layer index set by the compositor
361    * is numbered from bottom -> top, i.e. the bottom most layer has the
362    * index of 0 and increases upwards.
363    */
364   uint32_t total_layers = layers_.size();
365   layers.resize(total_layers);
366   total_layers -= 1;
367
368   for (std::pair<const iahwc_layer_t, IAHWCLayer>& l : layers_) {
369     IAHWCLayer& temp = l.second;
370     uint32_t layer_index = total_layers - temp.GetLayerIndex();
371     layers[layer_index] = temp.GetLayer();
372   }
373
374   native_display_->Present(layers, release_fd, this);
375
376   return IAHWC_ERROR_NONE;
377 }
378
379 int IAHWC::IAHWCDisplay::DisableOverlayUsage() {
380   native_display_->SetExplicitSyncSupport(false);
381   return 0;
382 }
383
384 int IAHWC::IAHWCDisplay::EnableOverlayUsage() {
385   native_display_->SetExplicitSyncSupport(true);
386   return 0;
387 }
388
389 void IAHWC::IAHWCDisplay::Synchronize() {
390   raw_data_uploader_->Synchronize();
391 }
392
393 int IAHWC::IAHWCDisplay::RegisterHotPlugCallback(
394   iahwc_callback_data_t data, iahwc_function_ptr_t func) {
395   auto callback = std::make_shared<IAHWCHotPlugEventCallback>(data, func, this);
396   //TODO:XXX send proper handle
397   native_display_->RegisterHotPlugCallback(std::move(callback),
398                                     static_cast<int>(0));
399   return IAHWC_ERROR_NONE;
400 }
401
402 int IAHWC::IAHWCDisplay::RunPixelUploader(bool enable) {
403   if (enable)
404     raw_data_uploader_->Initialize();
405   else
406     raw_data_uploader_->ExitThread();
407 }
408
409 int IAHWC::IAHWCDisplay::CreateLayer(uint32_t* layer_handle) {
410   *layer_handle = native_display_->AcquireId();
411   layers_.emplace(*layer_handle, IAHWCLayer(raw_data_uploader_));
412
413   return IAHWC_ERROR_NONE;
414 }
415
416 int IAHWC::IAHWCDisplay::DestroyLayer(uint32_t layer_handle) {
417   if (layers_.empty())
418     return IAHWC_ERROR_NONE;
419
420   if (layers_.erase(layer_handle))
421     native_display_->ReleaseId(layer_handle);
422
423   return IAHWC_ERROR_NONE;
424 }
425
426 int IAHWC::IAHWCDisplay::RegisterVsyncCallback(iahwc_callback_data_t data,
427                                                iahwc_function_ptr_t hook) {
428   auto callback = std::make_shared<IAHWCVsyncCallback>(data, hook);
429   native_display_->VSyncControl(true);
430   int ret = native_display_->RegisterVsyncCallback(std::move(callback),
431                                                    static_cast<int>(0));
432   if (ret) {
433     return IAHWC_ERROR_BAD_DISPLAY;
434   }
435   return IAHWC_ERROR_NONE;
436 }
437
438 void IAHWC::IAHWCDisplay::RegisterPixelUploaderCallback(
439     iahwc_callback_data_t data, iahwc_function_ptr_t hook) {
440   auto callback = std::make_shared<IAPixelUploaderCallback>(data, hook, 0);
441   raw_data_uploader_->RegisterPixelUploaderCallback(std::move(callback));
442 }
443
444 bool IAHWC::IAHWCDisplay::IsConnected() {
445   return native_display_->IsConnected();
446 }
447
448 IAHWC::IAHWCLayer::IAHWCLayer(PixelUploader* uploader)
449     : raw_data_uploader_(uploader) {
450   layer_usage_ = IAHWC_LAYER_USAGE_NORMAL;
451   layer_index_ = 0;
452   memset(&hwc_handle_.import_data, 0, sizeof(hwc_handle_.import_data));
453   memset(&hwc_handle_.meta_data_, 0, sizeof(hwc_handle_.meta_data_));
454   iahwc_layer_.SetBlending(hwcomposer::HWCBlending::kBlendingPremult);
455 }
456
457 IAHWC::IAHWCLayer::~IAHWCLayer() {
458   if (pixel_buffer_) {
459     const NativeBufferHandler* buffer_handler =
460         raw_data_uploader_->GetNativeBufferHandler();
461     if (upload_in_progress_) {
462       raw_data_uploader_->Synchronize();
463     }
464     buffer_handler->ReleaseBuffer(pixel_buffer_);
465     buffer_handler->DestroyHandle(pixel_buffer_);
466     pixel_buffer_ = NULL;
467   } else {
468     ClosePrimeHandles();
469   }
470 }
471
472 int IAHWC::IAHWCLayer::SetBo(gbm_bo* bo) {
473   int32_t width, height;
474
475   if (pixel_buffer_) {
476     const NativeBufferHandler* buffer_handler =
477         raw_data_uploader_->GetNativeBufferHandler();
478     if (upload_in_progress_) {
479       raw_data_uploader_->Synchronize();
480     }
481     buffer_handler->ReleaseBuffer(pixel_buffer_);
482     buffer_handler->DestroyHandle(pixel_buffer_);
483     pixel_buffer_ = NULL;
484   } else {
485     ClosePrimeHandles();
486   }
487
488   width = gbm_bo_get_width(bo);
489   height = gbm_bo_get_height(bo);
490
491 #if USE_MINIGBM
492   hwc_handle_.import_data.width = width;
493   hwc_handle_.import_data.height = height;
494   hwc_handle_.import_data.format = gbm_bo_get_format(bo);
495
496   size_t total_planes = gbm_bo_get_num_planes(bo);
497   for (size_t i = 0; i < total_planes; i++) {
498     hwc_handle_.import_data.fds[i] = gbm_bo_get_plane_fd(bo, i);
499     hwc_handle_.import_data.offsets[i] = gbm_bo_get_plane_offset(bo, i);
500     hwc_handle_.import_data.strides[i] = gbm_bo_get_plane_stride(bo, i);
501   }
502   temp->meta_data_.num_planes_ = total_planes;
503 #else
504   hwc_handle_.import_data.fd_data.width = width;
505   hwc_handle_.import_data.fd_data.height = height;
506   hwc_handle_.import_data.fd_data.format = gbm_bo_get_format(bo);
507   hwc_handle_.import_data.fd_data.fd = gbm_bo_get_fd(bo);
508   hwc_handle_.import_data.fd_data.stride = gbm_bo_get_stride(bo);
509   hwc_handle_.meta_data_.num_planes_ =
510       drm_bo_get_num_planes(hwc_handle_.import_data.fd_data.format);
511 #endif
512
513   hwc_handle_.bo = bo;
514   hwc_handle_.hwc_buffer_ = true;
515   hwc_handle_.gbm_flags = 0;
516
517   iahwc_layer_.SetNativeHandle(&hwc_handle_);
518
519   return IAHWC_ERROR_NONE;
520 }
521
522 int IAHWC::IAHWCLayer::SetRawPixelData(iahwc_raw_pixel_data bo) {
523   const NativeBufferHandler* buffer_handler =
524       raw_data_uploader_->GetNativeBufferHandler();
525   ClosePrimeHandles();
526   if (pixel_buffer_ &&
527       ((orig_height_ != bo.height) || (orig_stride_ != bo.stride))) {
528     if (upload_in_progress_) {
529       raw_data_uploader_->Synchronize();
530     }
531
532     buffer_handler->ReleaseBuffer(pixel_buffer_);
533     buffer_handler->DestroyHandle(pixel_buffer_);
534     pixel_buffer_ = NULL;
535   }
536
537   if (!pixel_buffer_) {
538     int layer_type =
539         layer_usage_ == IAHWC_LAYER_USAGE_CURSOR ? kLayerCursor : kLayerNormal;
540     bool modifier_used = false;
541     if (!buffer_handler->CreateBuffer(bo.width, bo.height, bo.format,
542                                       &pixel_buffer_, layer_type,
543                                       &modifier_used, 0, true)) {
544       ETRACE("PixelBuffer: CreateBuffer failed");
545       return -1;
546     }
547
548     if (!buffer_handler->ImportBuffer(pixel_buffer_)) {
549       ETRACE("PixelBuffer: ImportBuffer failed");
550       return -1;
551     }
552
553     if (pixel_buffer_->meta_data_.prime_fds_[0] <= 0) {
554       ETRACE("PixelBuffer: prime_fd_ is invalid.");
555       return -1;
556     }
557
558     orig_width_ = bo.width;
559     orig_height_ = bo.height;
560     orig_stride_ = bo.stride;
561     iahwc_layer_.SetNativeHandle(pixel_buffer_);
562   }
563
564   upload_in_progress_ = true;
565   raw_data_uploader_->UpdateLayerPixelData(
566       pixel_buffer_, orig_width_, orig_height_, orig_stride_, bo.callback_data,
567       (uint8_t*)bo.buffer, this, iahwc_layer_.GetSurfaceDamage());
568
569   return IAHWC_ERROR_NONE;
570 }
571
572 void IAHWC::IAHWCLayer::UploadDone() {
573   upload_in_progress_ = false;
574 }
575
576 int IAHWC::IAHWCLayer::SetAcquireFence(int32_t acquire_fence) {
577   iahwc_layer_.SetAcquireFence(acquire_fence);
578
579   return IAHWC_ERROR_NONE;
580 }
581
582 int IAHWC::IAHWCLayer::SetLayerUsage(int32_t layer_usage) {
583   if (layer_usage_ != layer_usage) {
584     layer_usage_ = layer_usage;
585     if (layer_usage_ == IAHWC_LAYER_USAGE_CURSOR) {
586       iahwc_layer_.MarkAsCursorLayer();
587     }
588
589     if (pixel_buffer_) {
590       const NativeBufferHandler* buffer_handler =
591           raw_data_uploader_->GetNativeBufferHandler();
592       buffer_handler->ReleaseBuffer(pixel_buffer_);
593       buffer_handler->DestroyHandle(pixel_buffer_);
594       pixel_buffer_ = NULL;
595     }
596   }
597
598   return IAHWC_ERROR_NONE;
599 }
600
601 int IAHWC::IAHWCLayer::SetLayerTransform(int32_t layer_transform) {
602   // 270* and 180* cannot be combined with flips. More specifically, they
603   // already contain both horizontal and vertical flips, so those fields are
604   // redundant in this case. 90* rotation can be combined with either horizontal
605   // flip or vertical flip, so treat it differently
606   int32_t temp = 0;
607   if (layer_transform == IAHWC_TRANSFORM_ROT_270) {
608     temp = hwcomposer::HWCTransform::kTransform270;
609   } else if (layer_transform == IAHWC_TRANSFORM_ROT_180) {
610     temp = hwcomposer::HWCTransform::kTransform180;
611   } else {
612     if (layer_transform & IAHWC_TRANSFORM_FLIP_H)
613       temp |= hwcomposer::HWCTransform::kReflectX;
614     if (layer_transform & IAHWC_TRANSFORM_FLIP_V)
615       temp |= hwcomposer::HWCTransform::kReflectY;
616     if (layer_transform & IAHWC_TRANSFORM_ROT_90)
617       temp |= hwcomposer::HWCTransform::kTransform90;
618   }
619   iahwc_layer_.SetTransform(temp);
620
621   return IAHWC_ERROR_NONE;
622 }
623
624 int IAHWC::IAHWCLayer::SetLayerSourceCrop(iahwc_rect_t rect) {
625   iahwc_layer_.SetSourceCrop(
626       hwcomposer::HwcRect<float>(rect.left, rect.top, rect.right, rect.bottom));
627
628   return IAHWC_ERROR_NONE;
629 }
630
631 int IAHWC::IAHWCLayer::SetLayerDisplayFrame(iahwc_rect_t rect) {
632   iahwc_layer_.SetDisplayFrame(
633       hwcomposer::HwcRect<float>(rect.left, rect.top, rect.right, rect.bottom),
634       0, 0);
635
636   return IAHWC_ERROR_NONE;
637 }
638
639 int IAHWC::IAHWCLayer::SetLayerSurfaceDamage(iahwc_region_t region) {
640   uint32_t num_rects = region.numRects;
641   hwcomposer::HwcRegion hwc_region;
642
643   for (size_t rect = 0; rect < num_rects; ++rect) {
644     hwc_region.emplace_back(region.rects[rect].left, region.rects[rect].top,
645                             region.rects[rect].right,
646                             region.rects[rect].bottom);
647   }
648
649   iahwc_layer_.SetSurfaceDamage(hwc_region);
650
651   return IAHWC_ERROR_NONE;
652 }
653
654 int IAHWC::IAHWCLayer::SetLayerPlaneAlpha(float alpha) {
655   iahwc_layer_.SetAlpha(alpha);
656   if (alpha != 1.0) {
657     iahwc_layer_.SetBlending(HWCBlending::kBlendingPremult);
658   }
659
660   return IAHWC_ERROR_NONE;
661 }
662
663 int IAHWC::IAHWCLayer::SetLayerIndex(uint32_t layer_index) {
664   layer_index_ = layer_index;
665
666   return IAHWC_ERROR_NONE;
667 }
668
669 hwcomposer::HwcLayer* IAHWC::IAHWCLayer::GetLayer() {
670   return &iahwc_layer_;
671 }
672
673 void IAHWC::IAHWCLayer::ClosePrimeHandles() {
674 #if USE_MINIGBM
675   size_t total_planes = hwc_handle_.meta_data_.num_planes_;
676   bool reset = false;
677   for (size_t i = 0; i < total_planes; i++) {
678     uint32_t fd = hwc_handle_.import_data.fds[i];
679     if (fd > 0) {
680       reset = true;
681       ::close(fd);
682     }
683   }
684
685   if (reset) {
686     memset(&hwc_handle_.import_data, 0, sizeof(hwc_handle_.import_data));
687   }
688 #else
689   if (hwc_handle_.import_data.fd_data.fd > 0) {
690     ::close(hwc_handle_.import_data.fd_data.fd);
691     memset(&hwc_handle_.import_data, 0, sizeof(hwc_handle_.import_data));
692     memset(&hwc_handle_.meta_data_, 0, sizeof(hwc_handle_.meta_data_));
693   }
694 #endif
695 }
696
697 }  // namespace hwcomposer
698
699 iahwc_module_t IAHWC_MODULE_INFO = {
700   .name = "IA Hardware Composer",
701   .open = hwcomposer::IAHWC::HookOpen,
702 };