OSDN Git Service

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