2 * Copyright (c) 2017 Intel Corporation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "linux_frontend.h"
18 #include <commondrmutils.h>
21 #include "nativebufferhandler.h"
23 #include "pixeluploader.h"
25 namespace hwcomposer {
27 class IAHWCVsyncCallback : public hwcomposer::VsyncCallback {
29 IAHWCVsyncCallback(iahwc_callback_data_t data, iahwc_function_ptr_t hook)
30 : data_(data), hook_(hook) {
33 void Callback(uint32_t display, int64_t timestamp) {
35 auto hook = reinterpret_cast<IAHWC_PFN_VSYNC>(hook_);
36 hook(data_, display, timestamp);
41 iahwc_callback_data_t data_;
42 iahwc_function_ptr_t hook_;
45 class IAPixelUploaderCallback : public hwcomposer::RawPixelUploadCallback {
47 IAPixelUploaderCallback(iahwc_callback_data_t data, iahwc_function_ptr_t hook,
49 : data_(data), hook_(hook), display_(display_id) {
52 void Callback(bool start_access, void* call_back_data) {
54 auto hook = reinterpret_cast<IAHWC_PFN_PIXEL_UPLOADER>(hook_);
55 hook(data_, display_, start_access ? 1 : 0, call_back_data);
60 iahwc_callback_data_t data_;
61 iahwc_function_ptr_t hook_;
65 class IAHWCHotPlugEventCallback : public hwcomposer::HotPlugCallback {
67 IAHWCHotPlugEventCallback(iahwc_callback_data_t data,
68 iahwc_function_ptr_t hook,
69 IAHWC::IAHWCDisplay *display)
70 : data_(data), hook_(hook), display_(display) {
73 void Callback(uint32_t display, bool connected) {
75 auto hook = reinterpret_cast<IAHWC_PFN_HOTPLUG>(hook_);
78 status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_CONNECTED);
80 display_->RunPixelUploader(true);
82 status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_DISCONNECTED);
84 display_->RunPixelUploader(false);
88 hook(data_, display, status);
93 iahwc_callback_data_t data_;
94 iahwc_function_ptr_t hook_;
95 IAHWC::IAHWCDisplay *display_;
99 getFunctionPtr = HookGetFunctionPtr;
103 int32_t IAHWC::Init() {
104 if (!device_.Initialize()) {
105 fprintf(stderr, "Unable to initialize GPU DEVICE");
106 return IAHWC_ERROR_NO_RESOURCES;
109 std::vector<hwcomposer::NativeDisplay*> displays = device_.GetAllDisplays();
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());
117 return IAHWC_ERROR_NONE;
120 int IAHWC::HookOpen(const iahwc_module_t* module, iahwc_device_t** device) {
121 IAHWC* iahwc = new IAHWC();
125 return IAHWC_ERROR_NONE;
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:
233 int IAHWC::HookClose(iahwc_device_t* dev) {
238 // private function implementations
240 int IAHWC::GetNumDisplays(int* num_displays) {
242 for (IAHWCDisplay* display : displays_) {
243 if (display->IsConnected())
247 return IAHWC_ERROR_NONE;
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);
260 case IAHWC_CALLBACK_PIXEL_UPLOADER: {
261 if (display_id >= displays_.size())
262 return IAHWC_ERROR_BAD_DISPLAY;
264 IAHWCDisplay* display = displays_.at(display_id);
265 display->RegisterPixelUploaderCallback(data, hook);
266 return IAHWC_ERROR_NONE;
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;
277 return IAHWC_ERROR_BAD_PARAMETER;
281 IAHWC::IAHWCDisplay::IAHWCDisplay() : native_display_(NULL) {
284 IAHWC::IAHWCDisplay::~IAHWCDisplay() {
285 delete raw_data_uploader_;
288 int IAHWC::IAHWCDisplay::Init(hwcomposer::NativeDisplay* display,
290 native_display_ = display;
291 native_display_->InitializeLayerHashGenerator(4);
293 new PixelUploader(native_display_->GetNativeBufferHandler());
296 int IAHWC::IAHWCDisplay::GetDisplayInfo(uint32_t config, int attribute,
298 hwcomposer::HWCDisplayAttribute attrib =
299 static_cast<hwcomposer::HWCDisplayAttribute>(attribute);
301 bool ret = native_display_->GetDisplayAttribute(config, attrib, value);
304 return IAHWC_ERROR_NO_RESOURCES;
306 return IAHWC_ERROR_NONE;
309 int IAHWC::IAHWCDisplay::GetDisplayName(uint32_t* size, char* name) {
310 bool ret = native_display_->GetDisplayName(size, name);
313 return IAHWC_ERROR_NO_RESOURCES;
315 return IAHWC_ERROR_NONE;
318 int IAHWC::IAHWCDisplay::GetDisplayConfigs(uint32_t* num_configs,
320 bool ret = native_display_->GetDisplayConfigs(num_configs, configs);
323 return IAHWC_ERROR_NO_RESOURCES;
325 return IAHWC_ERROR_NONE;
328 int IAHWC::IAHWCDisplay::SetDisplayGamma(float r, float b, float g) {
329 native_display_->SetGamma(r, g, b);
330 return IAHWC_ERROR_NONE;
333 int IAHWC::IAHWCDisplay::SetDisplayConfig(uint32_t config) {
334 bool ret = native_display_->SetActiveConfig(config);
337 return IAHWC_ERROR_NO_RESOURCES;
339 return IAHWC_ERROR_NONE;
342 int IAHWC::IAHWCDisplay::GetDisplayConfig(uint32_t* config) {
343 bool ret = native_display_->GetActiveConfig(config);
346 return IAHWC_ERROR_NO_RESOURCES;
348 return IAHWC_ERROR_NONE;
351 int IAHWC::IAHWCDisplay::ClearAllLayers() {
353 native_display_->ResetLayerHashGenerator();
355 return IAHWC_ERROR_NONE;
357 int IAHWC::IAHWCDisplay::PresentDisplay(int32_t* release_fd) {
358 std::vector<hwcomposer::HwcLayer*> layers;
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.
364 uint32_t total_layers = layers_.size();
365 layers.resize(total_layers);
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();
374 native_display_->Present(layers, release_fd, this);
376 return IAHWC_ERROR_NONE;
379 int IAHWC::IAHWCDisplay::DisableOverlayUsage() {
380 native_display_->SetExplicitSyncSupport(false);
384 int IAHWC::IAHWCDisplay::EnableOverlayUsage() {
385 native_display_->SetExplicitSyncSupport(true);
389 void IAHWC::IAHWCDisplay::Synchronize() {
390 raw_data_uploader_->Synchronize();
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;
402 int IAHWC::IAHWCDisplay::RunPixelUploader(bool enable) {
404 raw_data_uploader_->Initialize();
406 raw_data_uploader_->ExitThread();
409 int IAHWC::IAHWCDisplay::CreateLayer(uint32_t* layer_handle) {
410 *layer_handle = native_display_->AcquireId();
411 layers_.emplace(*layer_handle, IAHWCLayer(raw_data_uploader_));
413 return IAHWC_ERROR_NONE;
416 int IAHWC::IAHWCDisplay::DestroyLayer(uint32_t layer_handle) {
418 return IAHWC_ERROR_NONE;
420 if (layers_.erase(layer_handle))
421 native_display_->ReleaseId(layer_handle);
423 return IAHWC_ERROR_NONE;
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));
433 return IAHWC_ERROR_BAD_DISPLAY;
435 return IAHWC_ERROR_NONE;
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));
444 bool IAHWC::IAHWCDisplay::IsConnected() {
445 return native_display_->IsConnected();
448 IAHWC::IAHWCLayer::IAHWCLayer(PixelUploader* uploader)
449 : raw_data_uploader_(uploader) {
450 layer_usage_ = IAHWC_LAYER_USAGE_NORMAL;
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);
457 IAHWC::IAHWCLayer::~IAHWCLayer() {
459 const NativeBufferHandler* buffer_handler =
460 raw_data_uploader_->GetNativeBufferHandler();
461 if (upload_in_progress_) {
462 raw_data_uploader_->Synchronize();
464 buffer_handler->ReleaseBuffer(pixel_buffer_);
465 buffer_handler->DestroyHandle(pixel_buffer_);
466 pixel_buffer_ = NULL;
472 int IAHWC::IAHWCLayer::SetBo(gbm_bo* bo) {
473 int32_t width, height;
476 const NativeBufferHandler* buffer_handler =
477 raw_data_uploader_->GetNativeBufferHandler();
478 if (upload_in_progress_) {
479 raw_data_uploader_->Synchronize();
481 buffer_handler->ReleaseBuffer(pixel_buffer_);
482 buffer_handler->DestroyHandle(pixel_buffer_);
483 pixel_buffer_ = NULL;
488 width = gbm_bo_get_width(bo);
489 height = gbm_bo_get_height(bo);
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);
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);
502 temp->meta_data_.num_planes_ = total_planes;
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);
514 hwc_handle_.hwc_buffer_ = true;
515 hwc_handle_.gbm_flags = 0;
517 iahwc_layer_.SetNativeHandle(&hwc_handle_);
519 return IAHWC_ERROR_NONE;
522 int IAHWC::IAHWCLayer::SetRawPixelData(iahwc_raw_pixel_data bo) {
523 const NativeBufferHandler* buffer_handler =
524 raw_data_uploader_->GetNativeBufferHandler();
527 ((orig_height_ != bo.height) || (orig_stride_ != bo.stride))) {
528 if (upload_in_progress_) {
529 raw_data_uploader_->Synchronize();
532 buffer_handler->ReleaseBuffer(pixel_buffer_);
533 buffer_handler->DestroyHandle(pixel_buffer_);
534 pixel_buffer_ = NULL;
537 if (!pixel_buffer_) {
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");
548 if (!buffer_handler->ImportBuffer(pixel_buffer_)) {
549 ETRACE("PixelBuffer: ImportBuffer failed");
553 if (pixel_buffer_->meta_data_.prime_fds_[0] <= 0) {
554 ETRACE("PixelBuffer: prime_fd_ is invalid.");
558 orig_width_ = bo.width;
559 orig_height_ = bo.height;
560 orig_stride_ = bo.stride;
561 iahwc_layer_.SetNativeHandle(pixel_buffer_);
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());
569 return IAHWC_ERROR_NONE;
572 void IAHWC::IAHWCLayer::UploadDone() {
573 upload_in_progress_ = false;
576 int IAHWC::IAHWCLayer::SetAcquireFence(int32_t acquire_fence) {
577 iahwc_layer_.SetAcquireFence(acquire_fence);
579 return IAHWC_ERROR_NONE;
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();
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;
598 return IAHWC_ERROR_NONE;
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
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;
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;
619 iahwc_layer_.SetTransform(temp);
621 return IAHWC_ERROR_NONE;
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));
628 return IAHWC_ERROR_NONE;
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),
636 return IAHWC_ERROR_NONE;
639 int IAHWC::IAHWCLayer::SetLayerSurfaceDamage(iahwc_region_t region) {
640 uint32_t num_rects = region.numRects;
641 hwcomposer::HwcRegion hwc_region;
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);
649 iahwc_layer_.SetSurfaceDamage(hwc_region);
651 return IAHWC_ERROR_NONE;
654 int IAHWC::IAHWCLayer::SetLayerPlaneAlpha(float alpha) {
655 iahwc_layer_.SetAlpha(alpha);
657 iahwc_layer_.SetBlending(HWCBlending::kBlendingPremult);
660 return IAHWC_ERROR_NONE;
663 int IAHWC::IAHWCLayer::SetLayerIndex(uint32_t layer_index) {
664 layer_index_ = layer_index;
666 return IAHWC_ERROR_NONE;
669 hwcomposer::HwcLayer* IAHWC::IAHWCLayer::GetLayer() {
670 return &iahwc_layer_;
673 void IAHWC::IAHWCLayer::ClosePrimeHandles() {
675 size_t total_planes = hwc_handle_.meta_data_.num_planes_;
677 for (size_t i = 0; i < total_planes; i++) {
678 uint32_t fd = hwc_handle_.import_data.fds[i];
686 memset(&hwc_handle_.import_data, 0, sizeof(hwc_handle_.import_data));
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_));
697 } // namespace hwcomposer
699 iahwc_module_t IAHWC_MODULE_INFO = {
700 .name = "IA Hardware Composer",
701 .open = hwcomposer::IAHWC::HookOpen,