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) {
74 auto hook = reinterpret_cast<IAHWC_PFN_HOTPLUG>(hook_);
77 status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_CONNECTED);
79 display_->RunPixelUploader(true);
81 status = static_cast<uint32_t>(IAHWC_DISPLAY_STATUS_DISCONNECTED);
83 display_->RunPixelUploader(false);
87 hook(data_, display, status);
91 iahwc_callback_data_t data_;
92 iahwc_function_ptr_t hook_;
93 IAHWC::IAHWCDisplay* display_;
97 getFunctionPtr = HookGetFunctionPtr;
101 int32_t IAHWC::Init() {
102 if (!device_.Initialize()) {
103 fprintf(stderr, "Unable to initialize GPU DEVICE");
104 return IAHWC_ERROR_NO_RESOURCES;
107 const std::vector<hwcomposer::NativeDisplay*>& displays =
108 device_.GetAllDisplays();
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());
116 return IAHWC_ERROR_NONE;
119 int IAHWC::HookOpen(const iahwc_module_t* module, iahwc_device_t** device) {
120 IAHWC* iahwc = new IAHWC();
124 return IAHWC_ERROR_NONE;
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:
240 int IAHWC::HookClose(iahwc_device_t* dev) {
245 // private function implementations
247 int IAHWC::GetNumDisplays(int* num_displays) {
249 for (IAHWCDisplay* display : displays_) {
250 if (display->IsConnected())
254 return IAHWC_ERROR_NONE;
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);
267 case IAHWC_CALLBACK_PIXEL_UPLOADER: {
268 if (display_id >= displays_.size())
269 return IAHWC_ERROR_BAD_DISPLAY;
271 IAHWCDisplay* display = displays_.at(display_id);
272 display->RegisterPixelUploaderCallback(data, hook);
273 return IAHWC_ERROR_NONE;
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;
284 return IAHWC_ERROR_BAD_PARAMETER;
288 IAHWC::IAHWCDisplay::IAHWCDisplay() : native_display_(NULL) {
291 IAHWC::IAHWCDisplay::~IAHWCDisplay() {
292 delete raw_data_uploader_;
295 int IAHWC::IAHWCDisplay::Init(hwcomposer::NativeDisplay* display,
297 native_display_ = display;
298 native_display_->InitializeLayerHashGenerator(4);
300 new PixelUploader(native_display_->GetNativeBufferHandler());
304 int IAHWC::IAHWCDisplay::GetConnectionStatus(int32_t* value) {
305 *value = IsConnected();
307 return IAHWC_ERROR_NONE;
310 int IAHWC::IAHWCDisplay::GetDisplayInfo(uint32_t config, int attribute,
312 hwcomposer::HWCDisplayAttribute attrib =
313 static_cast<hwcomposer::HWCDisplayAttribute>(attribute);
315 bool ret = native_display_->GetDisplayAttribute(config, attrib, value);
318 return IAHWC_ERROR_NO_RESOURCES;
320 return IAHWC_ERROR_NONE;
323 int IAHWC::IAHWCDisplay::GetDisplayName(uint32_t* size, char* name) {
324 bool ret = native_display_->GetDisplayName(size, name);
327 return IAHWC_ERROR_NO_RESOURCES;
329 return IAHWC_ERROR_NONE;
332 int IAHWC::IAHWCDisplay::GetDisplayConfigs(uint32_t* num_configs,
334 bool ret = native_display_->GetDisplayConfigs(num_configs, configs);
337 return IAHWC_ERROR_NO_RESOURCES;
339 return IAHWC_ERROR_NONE;
342 int IAHWC::IAHWCDisplay::SetPowerMode(uint32_t power_mode) {
343 native_display_->SetPowerMode(power_mode);
345 return IAHWC_ERROR_NONE;
348 int IAHWC::IAHWCDisplay::SetDisplayGamma(float r, float b, float g) {
349 native_display_->SetGamma(r, g, b);
350 return IAHWC_ERROR_NONE;
353 int IAHWC::IAHWCDisplay::SetDisplayConfig(uint32_t config) {
354 bool ret = native_display_->SetActiveConfig(config);
357 return IAHWC_ERROR_NO_RESOURCES;
359 return IAHWC_ERROR_NONE;
362 int IAHWC::IAHWCDisplay::GetDisplayConfig(uint32_t* config) {
363 bool ret = native_display_->GetActiveConfig(config);
366 return IAHWC_ERROR_NO_RESOURCES;
368 return IAHWC_ERROR_NONE;
371 int IAHWC::IAHWCDisplay::ClearAllLayers() {
373 native_display_->ResetLayerHashGenerator();
375 return IAHWC_ERROR_NONE;
377 int IAHWC::IAHWCDisplay::PresentDisplay(int32_t* release_fd) {
378 std::vector<hwcomposer::HwcLayer*> layers;
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.
384 uint32_t total_layers = layers_.size();
385 layers.resize(total_layers);
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();
394 native_display_->Present(layers, release_fd, this);
396 return IAHWC_ERROR_NONE;
399 int IAHWC::IAHWCDisplay::DisableOverlayUsage() {
400 native_display_->SetExplicitSyncSupport(false);
404 int IAHWC::IAHWCDisplay::EnableOverlayUsage() {
405 native_display_->SetExplicitSyncSupport(true);
409 void IAHWC::IAHWCDisplay::Synchronize() {
410 raw_data_uploader_->Synchronize();
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;
422 int IAHWC::IAHWCDisplay::RunPixelUploader(bool enable) {
424 raw_data_uploader_->Initialize();
426 raw_data_uploader_->ExitThread();
430 int IAHWC::IAHWCDisplay::CreateLayer(uint32_t* layer_handle) {
431 *layer_handle = native_display_->AcquireId();
432 layers_.emplace(*layer_handle, IAHWCLayer(raw_data_uploader_));
434 return IAHWC_ERROR_NONE;
437 int IAHWC::IAHWCDisplay::DestroyLayer(uint32_t layer_handle) {
439 return IAHWC_ERROR_NONE;
441 if (layers_.erase(layer_handle))
442 native_display_->ReleaseId(layer_handle);
444 return IAHWC_ERROR_NONE;
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));
454 return IAHWC_ERROR_BAD_DISPLAY;
456 return IAHWC_ERROR_NONE;
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));
465 bool IAHWC::IAHWCDisplay::IsConnected() {
466 return native_display_->IsConnected();
469 IAHWC::IAHWCLayer::IAHWCLayer(PixelUploader* uploader)
470 : raw_data_uploader_(uploader) {
471 layer_usage_ = IAHWC_LAYER_USAGE_NORMAL;
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);
478 IAHWC::IAHWCLayer::~IAHWCLayer() {
480 const NativeBufferHandler* buffer_handler =
481 raw_data_uploader_->GetNativeBufferHandler();
482 if (upload_in_progress_) {
483 raw_data_uploader_->Synchronize();
485 buffer_handler->ReleaseBuffer(pixel_buffer_);
486 buffer_handler->DestroyHandle(pixel_buffer_);
487 pixel_buffer_ = NULL;
493 int IAHWC::IAHWCLayer::SetBo(gbm_bo* bo) {
494 int32_t width, height;
497 const NativeBufferHandler* buffer_handler =
498 raw_data_uploader_->GetNativeBufferHandler();
499 if (upload_in_progress_) {
500 raw_data_uploader_->Synchronize();
502 buffer_handler->ReleaseBuffer(pixel_buffer_);
503 buffer_handler->DestroyHandle(pixel_buffer_);
504 pixel_buffer_ = NULL;
509 width = gbm_bo_get_width(bo);
510 height = gbm_bo_get_height(bo);
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);
521 hwc_handle_.hwc_buffer_ = true;
522 hwc_handle_.gbm_flags = 0;
524 iahwc_layer_.SetNativeHandle(&hwc_handle_);
526 return IAHWC_ERROR_NONE;
529 int IAHWC::IAHWCLayer::SetRawPixelData(iahwc_raw_pixel_data bo) {
530 const NativeBufferHandler* buffer_handler =
531 raw_data_uploader_->GetNativeBufferHandler();
534 ((orig_height_ != bo.height) || (orig_stride_ != bo.stride))) {
535 if (upload_in_progress_) {
536 raw_data_uploader_->Synchronize();
539 buffer_handler->ReleaseBuffer(pixel_buffer_);
540 buffer_handler->DestroyHandle(pixel_buffer_);
541 pixel_buffer_ = NULL;
544 if (!pixel_buffer_) {
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");
555 if (!buffer_handler->ImportBuffer(pixel_buffer_)) {
556 ETRACE("PixelBuffer: ImportBuffer failed");
560 if (pixel_buffer_->meta_data_.prime_fds_[0] <= 0) {
561 ETRACE("PixelBuffer: prime_fd_ is invalid.");
565 orig_width_ = bo.width;
566 orig_height_ = bo.height;
567 orig_stride_ = bo.stride;
568 iahwc_layer_.SetNativeHandle(pixel_buffer_);
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());
576 return IAHWC_ERROR_NONE;
579 void IAHWC::IAHWCLayer::UploadDone() {
580 upload_in_progress_ = false;
583 int IAHWC::IAHWCLayer::SetAcquireFence(int32_t acquire_fence) {
584 iahwc_layer_.SetAcquireFence(acquire_fence);
586 return IAHWC_ERROR_NONE;
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();
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;
605 return IAHWC_ERROR_NONE;
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
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;
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;
626 iahwc_layer_.SetTransform(temp);
628 return IAHWC_ERROR_NONE;
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));
635 return IAHWC_ERROR_NONE;
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),
643 return IAHWC_ERROR_NONE;
646 int IAHWC::IAHWCLayer::SetLayerSurfaceDamage(iahwc_region_t region) {
647 uint32_t num_rects = region.numRects;
648 hwcomposer::HwcRegion hwc_region;
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);
656 iahwc_layer_.SetSurfaceDamage(hwc_region);
658 return IAHWC_ERROR_NONE;
661 int IAHWC::IAHWCLayer::SetLayerPlaneAlpha(float alpha) {
662 iahwc_layer_.SetAlpha(alpha);
664 iahwc_layer_.SetBlending(HWCBlending::kBlendingPremult);
667 return IAHWC_ERROR_NONE;
670 int IAHWC::IAHWCLayer::SetLayerIndex(uint32_t layer_index) {
671 layer_index_ = layer_index;
673 return IAHWC_ERROR_NONE;
676 hwcomposer::HwcLayer* IAHWC::IAHWCLayer::GetLayer() {
677 return &iahwc_layer_;
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_));
688 } // namespace hwcomposer
690 iahwc_module_t IAHWC_MODULE_INFO = {
691 .name = "IA Hardware Composer", .open = hwcomposer::IAHWC::HookOpen,