1 /*
2 * Copyright 2016 The Android Open Source Project
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 #include "impl/vr_hwc.h"
17
18 #include "android-base/stringprintf.h"
19 #include <cutils/properties.h>
20 #include <private/dvr/display_client.h>
21 #include <ui/Fence.h>
22
23 #include <mutex>
24
25 #include "vr_composer_client.h"
26
27 using namespace android::hardware::graphics::common::V1_0;
28 using namespace android::hardware::graphics::composer::V2_1;
29
30 using android::base::StringPrintf;
31 using android::hardware::hidl_handle;
32 using android::hardware::hidl_string;
33 using android::hardware::hidl_vec;
34 using android::hardware::Return;
35 using android::hardware::Void;
36
37 namespace android {
38 namespace dvr {
39 namespace {
40
41 using android::hardware::graphics::common::V1_0::PixelFormat;
42
43 const Display kDefaultDisplayId = 1;
44 const Config kDefaultConfigId = 1;
45
CreateGraphicBuffer(const native_handle_t * handle,const IVrComposerClient::BufferMetadata & metadata)46 sp<GraphicBuffer> CreateGraphicBuffer(
47 const native_handle_t* handle,
48 const IVrComposerClient::BufferMetadata& metadata) {
49 sp<GraphicBuffer> buffer = new GraphicBuffer(
50 handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height,
51 static_cast<int32_t>(metadata.format), metadata.layerCount,
52 metadata.usage, metadata.stride);
53 if (buffer->initCheck() != OK) {
54 ALOGE("Failed to create graphic buffer");
55 return nullptr;
56 }
57
58 return buffer;
59 }
60
GetPrimaryDisplaySize(int32_t * width,int32_t * height)61 void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
62 *width = 1080;
63 *height = 1920;
64
65 int error = 0;
66 auto display_client = display::DisplayClient::Create(&error);
67 if (!display_client) {
68 ALOGE("Could not connect to display service : %s(%d)", strerror(error),
69 error);
70 return;
71 }
72
73 auto status = display_client->GetDisplayMetrics();
74 if (!status) {
75 ALOGE("Could not get display metrics from display service : %s(%d)",
76 status.GetErrorMessage().c_str(), status.error());
77 return;
78 }
79
80 *width = status.get().display_width;
81 *height = status.get().display_height;
82 }
83
84 } // namespace
85
HwcDisplay(int32_t width,int32_t height)86 HwcDisplay::HwcDisplay(int32_t width, int32_t height)
87 : width_(width), height_(height) {}
88
~HwcDisplay()89 HwcDisplay::~HwcDisplay() {}
90
SetClientTarget(const native_handle_t * handle,base::unique_fd fence)91 bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
92 base::unique_fd fence) {
93 if (handle)
94 buffer_ = CreateGraphicBuffer(handle, buffer_metadata_);
95
96 fence_ = new Fence(fence.release());
97 return true;
98 }
99
SetClientTargetMetadata(const IVrComposerClient::BufferMetadata & metadata)100 void HwcDisplay::SetClientTargetMetadata(
101 const IVrComposerClient::BufferMetadata& metadata) {
102 buffer_metadata_ = metadata;
103 }
104
CreateLayer()105 HwcLayer* HwcDisplay::CreateLayer() {
106 uint64_t layer_id = layer_ids_++;
107 layers_.push_back(HwcLayer(layer_id));
108 return &layers_.back();
109 }
110
GetLayer(Layer id)111 HwcLayer* HwcDisplay::GetLayer(Layer id) {
112 for (size_t i = 0; i < layers_.size(); ++i)
113 if (layers_[i].info.id == id)
114 return &layers_[i];
115
116 return nullptr;
117 }
118
DestroyLayer(Layer id)119 bool HwcDisplay::DestroyLayer(Layer id) {
120 for (auto it = layers_.begin(); it != layers_.end(); ++it) {
121 if (it->info.id == id) {
122 layers_.erase(it);
123 return true;
124 }
125 }
126
127 return false;
128 }
129
GetChangedCompositionTypes(std::vector<Layer> * layer_ids,std::vector<IComposerClient::Composition> * types)130 void HwcDisplay::GetChangedCompositionTypes(
131 std::vector<Layer>* layer_ids,
132 std::vector<IComposerClient::Composition>* types) {
133 std::sort(layers_.begin(), layers_.end(),
134 [](const auto& lhs, const auto& rhs) {
135 return lhs.info.z_order < rhs.info.z_order;
136 });
137
138 const size_t no_layer = std::numeric_limits<size_t>::max();
139 size_t first_client_layer = no_layer, last_client_layer = no_layer;
140 for (size_t i = 0; i < layers_.size(); ++i) {
141 switch (layers_[i].composition_type) {
142 case IComposerClient::Composition::SOLID_COLOR:
143 case IComposerClient::Composition::CURSOR:
144 case IComposerClient::Composition::SIDEBAND:
145 if (first_client_layer == no_layer)
146 first_client_layer = i;
147
148 last_client_layer = i;
149 break;
150 default:
151 break;
152 }
153 }
154
155 for (size_t i = 0; i < layers_.size(); ++i) {
156 if (i >= first_client_layer && i <= last_client_layer) {
157 if (layers_[i].composition_type != IComposerClient::Composition::CLIENT) {
158 layer_ids->push_back(layers_[i].info.id);
159 types->push_back(IComposerClient::Composition::CLIENT);
160 layers_[i].composition_type = IComposerClient::Composition::CLIENT;
161 }
162
163 continue;
164 }
165
166 if (layers_[i].composition_type != IComposerClient::Composition::DEVICE) {
167 layer_ids->push_back(layers_[i].info.id);
168 types->push_back(IComposerClient::Composition::DEVICE);
169 layers_[i].composition_type = IComposerClient::Composition::DEVICE;
170 }
171 }
172 }
173
GetFrame(std::vector<ComposerView::ComposerLayer> * out_frames)174 Error HwcDisplay::GetFrame(
175 std::vector<ComposerView::ComposerLayer>* out_frames) {
176 bool queued_client_target = false;
177 std::vector<ComposerView::ComposerLayer> frame;
178 for (const auto& layer : layers_) {
179 if (layer.composition_type == IComposerClient::Composition::CLIENT) {
180 if (queued_client_target)
181 continue;
182
183 if (!buffer_.get()) {
184 ALOGE("Client composition requested but no client target buffer");
185 return Error::BAD_LAYER;
186 }
187
188 ComposerView::ComposerLayer client_target_layer = {
189 .buffer = buffer_,
190 .fence = fence_.get() ? fence_ : new Fence(-1),
191 .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
192 static_cast<int32_t>(buffer_->getHeight())},
193 .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
194 static_cast<float>(buffer_->getHeight())},
195 .blend_mode = IComposerClient::BlendMode::NONE,
196 };
197
198 frame.push_back(client_target_layer);
199 queued_client_target = true;
200 } else {
201 if (!layer.info.buffer.get() || !layer.info.fence.get()) {
202 ALOGV("Layer requested without valid buffer");
203 continue;
204 }
205
206 frame.push_back(layer.info);
207 }
208 }
209
210 out_frames->swap(frame);
211 return Error::NONE;
212 }
213
UpdateLastFrameAndGetLastFrameLayers()214 std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
215 std::vector<Layer> last_frame_layers;
216 last_frame_layers.swap(last_frame_layers_ids_);
217
218 for (const auto& layer : layers_)
219 last_frame_layers_ids_.push_back(layer.info.id);
220
221 return last_frame_layers;
222 }
223
SetColorTransform(const float * matrix,int32_t hint)224 void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) {
225 color_transform_hint_ = hint;
226 if (matrix)
227 memcpy(color_transform_, matrix, sizeof(color_transform_));
228 }
229
dumpDebugInfo(std::string * result) const230 void HwcDisplay::dumpDebugInfo(std::string* result) const {
231 if (!result) {
232 return;
233 }
234 *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\
235 , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_);
236 *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\
237 layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height,
238 buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format);
239 for (const auto& layer : layers_) {
240 layer.dumpDebugInfo(result);
241 }
242 }
243
244 ////////////////////////////////////////////////////////////////////////////////
245 // VrHwcClient
246
VrHwc()247 VrHwc::VrHwc() {}
248
~VrHwc()249 VrHwc::~VrHwc() {}
250
hasCapability(hwc2_capability_t)251 bool VrHwc::hasCapability(hwc2_capability_t /* capability */) { return false; }
252
registerEventCallback(EventCallback * callback)253 void VrHwc::registerEventCallback(EventCallback* callback) {
254 {
255 std::lock_guard<std::mutex> guard(mutex_);
256 event_callback_ = callback;
257 int32_t width, height;
258 GetPrimaryDisplaySize(&width, &height);
259 // Create the primary display late to avoid initialization issues between
260 // VR HWC and SurfaceFlinger.
261 displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height));
262 }
263 event_callback_->onHotplug(kDefaultDisplayId,
264 IComposerCallback::Connection::CONNECTED);
265 }
266
unregisterEventCallback()267 void VrHwc::unregisterEventCallback() {
268 std::lock_guard<std::mutex> guard(mutex_);
269 event_callback_ = nullptr;
270 }
271
getMaxVirtualDisplayCount()272 uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; }
273
createVirtualDisplay(uint32_t width,uint32_t height,PixelFormat * format,Display * outDisplay)274 Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
275 PixelFormat* format, Display* outDisplay) {
276 *format = PixelFormat::RGBA_8888;
277 *outDisplay = display_count_;
278 displays_[display_count_].reset(new HwcDisplay(width, height));
279 display_count_++;
280 return Error::NONE;
281 }
282
destroyVirtualDisplay(Display display)283 Error VrHwc::destroyVirtualDisplay(Display display) {
284 std::lock_guard<std::mutex> guard(mutex_);
285 if (display == kDefaultDisplayId || displays_.erase(display) == 0)
286 return Error::BAD_DISPLAY;
287 ComposerView::Frame frame;
288 frame.display_id = display;
289 frame.removed = true;
290 if (observer_)
291 observer_->OnNewFrame(frame);
292 return Error::NONE;
293 }
294
createLayer(Display display,Layer * outLayer)295 Error VrHwc::createLayer(Display display, Layer* outLayer) {
296 std::lock_guard<std::mutex> guard(mutex_);
297 auto display_ptr = FindDisplay(display);
298 if (!display_ptr)
299 return Error::BAD_DISPLAY;
300
301 HwcLayer* layer = display_ptr->CreateLayer();
302 *outLayer = layer->info.id;
303 return Error::NONE;
304 }
305
destroyLayer(Display display,Layer layer)306 Error VrHwc::destroyLayer(Display display, Layer layer) {
307 std::lock_guard<std::mutex> guard(mutex_);
308 auto display_ptr = FindDisplay(display);
309 if (!display_ptr) {
310 return Error::BAD_DISPLAY;
311 }
312
313 return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
314 }
315
getActiveConfig(Display display,Config * outConfig)316 Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
317 std::lock_guard<std::mutex> guard(mutex_);
318 if (!FindDisplay(display))
319 return Error::BAD_DISPLAY;
320 *outConfig = kDefaultConfigId;
321 return Error::NONE;
322 }
323
getClientTargetSupport(Display,uint32_t,uint32_t,PixelFormat,Dataspace)324 Error VrHwc::getClientTargetSupport(Display /* display */, uint32_t /* width */,
325 uint32_t /* height */,
326 PixelFormat /* format */,
327 Dataspace /* dataspace */) {
328 return Error::NONE;
329 }
330
getColorModes(Display,hidl_vec<ColorMode> * outModes)331 Error VrHwc::getColorModes(Display /* display */,
332 hidl_vec<ColorMode>* outModes) {
333 std::vector<ColorMode> color_modes(1, ColorMode::NATIVE);
334 *outModes = hidl_vec<ColorMode>(color_modes);
335 return Error::NONE;
336 }
337
getDisplayAttribute(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)338 Error VrHwc::getDisplayAttribute(Display display, Config config,
339 IComposerClient::Attribute attribute,
340 int32_t* outValue) {
341 std::lock_guard<std::mutex> guard(mutex_);
342 auto display_ptr = FindDisplay(display);
343 if (!display_ptr) {
344 return Error::BAD_DISPLAY;
345 }
346 if (config != kDefaultConfigId) {
347 return Error::BAD_CONFIG;
348 }
349
350 switch (attribute) {
351 case IComposerClient::Attribute::WIDTH:
352 *outValue = display_ptr->width();
353 break;
354 case IComposerClient::Attribute::HEIGHT:
355 *outValue = display_ptr->height();
356 break;
357 case IComposerClient::Attribute::VSYNC_PERIOD:
358 {
359 int error = 0;
360 auto display_client = display::DisplayClient::Create(&error);
361 if (!display_client) {
362 ALOGE("Could not connect to display service : %s(%d)",
363 strerror(error), error);
364 // Return a default value of 30 fps
365 *outValue = 1000 * 1000 * 1000 / 30;
366 } else {
367 auto metrics = display_client->GetDisplayMetrics();
368 *outValue = metrics.get().vsync_period_ns;
369 }
370 }
371 break;
372 case IComposerClient::Attribute::DPI_X:
373 case IComposerClient::Attribute::DPI_Y:
374 {
375 constexpr int32_t kDefaultDPI = 300;
376 int32_t dpi = property_get_int32("ro.vr.hwc.dpi", kDefaultDPI);
377 if (dpi <= 0) {
378 dpi = kDefaultDPI;
379 }
380 *outValue = 1000 * dpi;
381 }
382 break;
383 default:
384 return Error::BAD_PARAMETER;
385 }
386
387 return Error::NONE;
388 }
389
getDisplayConfigs(Display display,hidl_vec<Config> * outConfigs)390 Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
391 std::lock_guard<std::mutex> guard(mutex_);
392 if (!FindDisplay(display))
393 return Error::BAD_DISPLAY;
394 std::vector<Config> configs(1, kDefaultConfigId);
395 *outConfigs = hidl_vec<Config>(configs);
396 return Error::NONE;
397 }
398
getDisplayName(Display,hidl_string * outName)399 Error VrHwc::getDisplayName(Display /* display */, hidl_string* outName) {
400 *outName = hidl_string();
401 return Error::NONE;
402 }
403
getDisplayType(Display display,IComposerClient::DisplayType * outType)404 Error VrHwc::getDisplayType(Display display,
405 IComposerClient::DisplayType* outType) {
406 std::lock_guard<std::mutex> guard(mutex_);
407 auto display_ptr = FindDisplay(display);
408 if (!display_ptr) {
409 *outType = IComposerClient::DisplayType::INVALID;
410 return Error::BAD_DISPLAY;
411 }
412
413 if (display == kDefaultDisplayId)
414 *outType = IComposerClient::DisplayType::PHYSICAL;
415 else
416 *outType = IComposerClient::DisplayType::VIRTUAL;
417
418 return Error::NONE;
419 }
420
getDozeSupport(Display display,bool * outSupport)421 Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
422 *outSupport = false;
423 std::lock_guard<std::mutex> guard(mutex_);
424 if (!FindDisplay(display))
425 return Error::BAD_DISPLAY;
426 return Error::NONE;
427 }
428
getHdrCapabilities(Display,hidl_vec<Hdr> *,float * outMaxLuminance,float * outMaxAverageLuminance,float * outMinLuminance)429 Error VrHwc::getHdrCapabilities(Display /* display */,
430 hidl_vec<Hdr>* /* outTypes */,
431 float* outMaxLuminance,
432 float* outMaxAverageLuminance,
433 float* outMinLuminance) {
434 *outMaxLuminance = 0;
435 *outMaxAverageLuminance = 0;
436 *outMinLuminance = 0;
437 return Error::NONE;
438 }
439
setActiveConfig(Display display,Config config)440 Error VrHwc::setActiveConfig(Display display, Config config) {
441 std::lock_guard<std::mutex> guard(mutex_);
442 auto display_ptr = FindDisplay(display);
443 if (!display_ptr)
444 return Error::BAD_DISPLAY;
445 if (config != kDefaultConfigId)
446 return Error::BAD_CONFIG;
447
448 display_ptr->set_active_config(config);
449 return Error::NONE;
450 }
451
setColorMode(Display display,ColorMode mode)452 Error VrHwc::setColorMode(Display display, ColorMode mode) {
453 std::lock_guard<std::mutex> guard(mutex_);
454 auto display_ptr = FindDisplay(display);
455 if (!display_ptr)
456 return Error::BAD_DISPLAY;
457
458 display_ptr->set_color_mode(mode);
459 return Error::NONE;
460 }
461
setPowerMode(Display display,IComposerClient::PowerMode mode)462 Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
463 std::lock_guard<std::mutex> guard(mutex_);
464 auto display_ptr = FindDisplay(display);
465 if (!display_ptr)
466 return Error::BAD_DISPLAY;
467
468 display_ptr->set_power_mode(mode);
469 return Error::NONE;
470 }
471
setVsyncEnabled(Display display,IComposerClient::Vsync enabled)472 Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
473 std::lock_guard<std::mutex> guard(mutex_);
474 auto display_ptr = FindDisplay(display);
475 if (!display_ptr)
476 return Error::BAD_DISPLAY;
477
478 display_ptr->set_vsync_enabled(enabled);
479 return Error::NONE;
480 }
481
setColorTransform(Display display,const float * matrix,int32_t hint)482 Error VrHwc::setColorTransform(Display display, const float* matrix,
483 int32_t hint) {
484 std::lock_guard<std::mutex> guard(mutex_);
485 auto display_ptr = FindDisplay(display);
486 if (!display_ptr)
487 return Error::BAD_DISPLAY;
488
489 display_ptr->SetColorTransform(matrix, hint);
490 return Error::NONE;
491 }
492
setClientTarget(Display display,buffer_handle_t target,int32_t acquireFence,int32_t,const std::vector<hwc_rect_t> &)493 Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
494 int32_t acquireFence, int32_t /* dataspace */,
495 const std::vector<hwc_rect_t>& /* damage */) {
496 base::unique_fd fence(acquireFence);
497 std::lock_guard<std::mutex> guard(mutex_);
498 auto display_ptr = FindDisplay(display);
499 if (!display_ptr)
500 return Error::BAD_DISPLAY;
501
502 if (target == nullptr)
503 return Error::NONE;
504
505 if (!display_ptr->SetClientTarget(target, std::move(fence)))
506 return Error::BAD_PARAMETER;
507
508 return Error::NONE;
509 }
510
setOutputBuffer(Display display,buffer_handle_t,int32_t releaseFence)511 Error VrHwc::setOutputBuffer(Display display, buffer_handle_t /* buffer */,
512 int32_t releaseFence) {
513 base::unique_fd fence(releaseFence);
514 std::lock_guard<std::mutex> guard(mutex_);
515 auto display_ptr = FindDisplay(display);
516 if (!display_ptr)
517 return Error::BAD_DISPLAY;
518
519 // TODO(dnicoara): Is it necessary to do anything here?
520 return Error::NONE;
521 }
522
validateDisplay(Display display,std::vector<Layer> * outChangedLayers,std::vector<IComposerClient::Composition> * outCompositionTypes,uint32_t *,std::vector<Layer> *,std::vector<uint32_t> *)523 Error VrHwc::validateDisplay(
524 Display display, std::vector<Layer>* outChangedLayers,
525 std::vector<IComposerClient::Composition>* outCompositionTypes,
526 uint32_t* /* outDisplayRequestMask */,
527 std::vector<Layer>* /* outRequestedLayers */,
528 std::vector<uint32_t>* /* outRequestMasks */) {
529 std::lock_guard<std::mutex> guard(mutex_);
530 auto display_ptr = FindDisplay(display);
531 if (!display_ptr)
532 return Error::BAD_DISPLAY;
533
534 display_ptr->GetChangedCompositionTypes(outChangedLayers,
535 outCompositionTypes);
536 return Error::NONE;
537 }
538
acceptDisplayChanges(Display)539 Error VrHwc::acceptDisplayChanges(Display /* display */) { return Error::NONE; }
540
presentDisplay(Display display,int32_t * outPresentFence,std::vector<Layer> * outLayers,std::vector<int32_t> * outReleaseFences)541 Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
542 std::vector<Layer>* outLayers,
543 std::vector<int32_t>* outReleaseFences) {
544 *outPresentFence = -1;
545 outLayers->clear();
546 outReleaseFences->clear();
547
548 std::lock_guard<std::mutex> guard(mutex_);
549 auto display_ptr = FindDisplay(display);
550
551 if (!display_ptr)
552 return Error::BAD_DISPLAY;
553
554 ComposerView::Frame frame;
555 std::vector<Layer> last_frame_layers;
556 Error status = display_ptr->GetFrame(&frame.layers);
557 frame.display_id = display;
558 frame.display_width = display_ptr->width();
559 frame.display_height = display_ptr->height();
560 frame.active_config = display_ptr->active_config();
561 frame.power_mode = display_ptr->power_mode();
562 frame.vsync_enabled = display_ptr->vsync_enabled();
563 frame.color_transform_hint = display_ptr->color_transform_hint();
564 frame.color_mode = display_ptr->color_mode();
565 memcpy(frame.color_transform, display_ptr->color_transform(),
566 sizeof(frame.color_transform));
567 if (status != Error::NONE)
568 return status;
569
570 last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers();
571
572 base::unique_fd fence;
573 if (observer_)
574 fence = observer_->OnNewFrame(frame);
575
576 if (fence.get() < 0)
577 return Error::NONE;
578
579 *outPresentFence = dup(fence.get());
580 outLayers->swap(last_frame_layers);
581 for (size_t i = 0; i < outLayers->size(); ++i)
582 outReleaseFences->push_back(dup(fence.get()));
583
584 return Error::NONE;
585 }
586
setLayerCursorPosition(Display display,Layer layer,int32_t x,int32_t y)587 Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
588 int32_t y) {
589 std::lock_guard<std::mutex> guard(mutex_);
590 auto display_ptr = FindDisplay(display);
591 if (!display_ptr)
592 return Error::BAD_DISPLAY;
593
594 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
595 if (!hwc_layer)
596 return Error::BAD_LAYER;
597
598 hwc_layer->info.cursor_x = x;
599 hwc_layer->info.cursor_y = y;
600 return Error::NONE;
601 }
602
setLayerBuffer(Display display,Layer layer,buffer_handle_t buffer,int32_t acquireFence)603 Error VrHwc::setLayerBuffer(Display display, Layer layer,
604 buffer_handle_t buffer, int32_t acquireFence) {
605 base::unique_fd fence(acquireFence);
606 std::lock_guard<std::mutex> guard(mutex_);
607 auto display_ptr = FindDisplay(display);
608 if (!display_ptr)
609 return Error::BAD_DISPLAY;
610
611 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
612 if (!hwc_layer)
613 return Error::BAD_LAYER;
614
615 hwc_layer->info.buffer = CreateGraphicBuffer(
616 buffer, hwc_layer->buffer_metadata);
617 hwc_layer->info.fence = new Fence(fence.release());
618
619 return Error::NONE;
620 }
621
setLayerSurfaceDamage(Display display,Layer layer,const std::vector<hwc_rect_t> & damage)622 Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
623 const std::vector<hwc_rect_t>& damage) {
624 std::lock_guard<std::mutex> guard(mutex_);
625 auto display_ptr = FindDisplay(display);
626 if (!display_ptr)
627 return Error::BAD_DISPLAY;
628
629 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
630 if (!hwc_layer)
631 return Error::BAD_LAYER;
632
633 hwc_layer->info.damaged_regions = damage;
634 return Error::NONE;
635 }
636
setLayerBlendMode(Display display,Layer layer,int32_t mode)637 Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
638 std::lock_guard<std::mutex> guard(mutex_);
639 auto display_ptr = FindDisplay(display);
640 if (!display_ptr)
641 return Error::BAD_DISPLAY;
642
643 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
644 if (!hwc_layer)
645 return Error::BAD_LAYER;
646
647 hwc_layer->info.blend_mode =
648 static_cast<ComposerView::ComposerLayer::BlendMode>(mode);
649
650 return Error::NONE;
651 }
652
setLayerColor(Display display,Layer layer,IComposerClient::Color color)653 Error VrHwc::setLayerColor(Display display, Layer layer,
654 IComposerClient::Color color) {
655 std::lock_guard<std::mutex> guard(mutex_);
656 auto display_ptr = FindDisplay(display);
657 if (!display_ptr)
658 return Error::BAD_DISPLAY;
659
660 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
661 if (!hwc_layer)
662 return Error::BAD_LAYER;
663
664 hwc_layer->info.color = color;
665 return Error::NONE;
666 }
667
setLayerCompositionType(Display display,Layer layer,int32_t type)668 Error VrHwc::setLayerCompositionType(Display display, Layer layer,
669 int32_t type) {
670 std::lock_guard<std::mutex> guard(mutex_);
671 auto display_ptr = FindDisplay(display);
672 if (!display_ptr)
673 return Error::BAD_DISPLAY;
674
675 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
676 if (!hwc_layer)
677 return Error::BAD_LAYER;
678
679 hwc_layer->composition_type = static_cast<HwcLayer::Composition>(type);
680
681 return Error::NONE;
682 }
683
setLayerDataspace(Display display,Layer layer,int32_t dataspace)684 Error VrHwc::setLayerDataspace(Display display, Layer layer,
685 int32_t dataspace) {
686 std::lock_guard<std::mutex> guard(mutex_);
687 auto display_ptr = FindDisplay(display);
688 if (!display_ptr)
689 return Error::BAD_DISPLAY;
690
691 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
692 if (!hwc_layer)
693 return Error::BAD_LAYER;
694
695 hwc_layer->info.dataspace = dataspace;
696 return Error::NONE;
697 }
698
setLayerDisplayFrame(Display display,Layer layer,const hwc_rect_t & frame)699 Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
700 const hwc_rect_t& frame) {
701 std::lock_guard<std::mutex> guard(mutex_);
702 auto display_ptr = FindDisplay(display);
703 if (!display_ptr)
704 return Error::BAD_DISPLAY;
705
706 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
707 if (!hwc_layer)
708 return Error::BAD_LAYER;
709
710 hwc_layer->info.display_frame =
711 {frame.left, frame.top, frame.right, frame.bottom};
712
713 return Error::NONE;
714 }
715
setLayerPlaneAlpha(Display display,Layer layer,float alpha)716 Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
717 std::lock_guard<std::mutex> guard(mutex_);
718 auto display_ptr = FindDisplay(display);
719 if (!display_ptr)
720 return Error::BAD_DISPLAY;
721
722 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
723 if (!hwc_layer)
724 return Error::BAD_LAYER;
725
726 hwc_layer->info.alpha = alpha;
727
728 return Error::NONE;
729 }
730
setLayerSidebandStream(Display display,Layer,buffer_handle_t)731 Error VrHwc::setLayerSidebandStream(Display display, Layer /* layer */,
732 buffer_handle_t /* stream */) {
733 std::lock_guard<std::mutex> guard(mutex_);
734 if (!FindDisplay(display))
735 return Error::BAD_DISPLAY;
736 return Error::NONE;
737 }
738
setLayerSourceCrop(Display display,Layer layer,const hwc_frect_t & crop)739 Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
740 const hwc_frect_t& crop) {
741 std::lock_guard<std::mutex> guard(mutex_);
742 auto display_ptr = FindDisplay(display);
743 if (!display_ptr)
744 return Error::BAD_DISPLAY;
745
746 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
747 if (!hwc_layer)
748 return Error::BAD_LAYER;
749
750 hwc_layer->info.crop = {crop.left, crop.top, crop.right, crop.bottom};
751
752 return Error::NONE;
753 }
754
setLayerTransform(Display display,Layer layer,int32_t transform)755 Error VrHwc::setLayerTransform(Display display, Layer layer,
756 int32_t transform) {
757 std::lock_guard<std::mutex> guard(mutex_);
758 auto display_ptr = FindDisplay(display);
759 if (!display_ptr)
760 return Error::BAD_DISPLAY;
761
762 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
763 if (!hwc_layer)
764 return Error::BAD_LAYER;
765
766 hwc_layer->info.transform = transform;
767 return Error::NONE;
768 }
769
setLayerVisibleRegion(Display display,Layer layer,const std::vector<hwc_rect_t> & visible)770 Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
771 const std::vector<hwc_rect_t>& visible) {
772 std::lock_guard<std::mutex> guard(mutex_);
773 auto display_ptr = FindDisplay(display);
774 if (!display_ptr)
775 return Error::BAD_DISPLAY;
776
777 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
778 if (!hwc_layer)
779 return Error::BAD_LAYER;
780
781 hwc_layer->info.visible_regions = visible;
782 return Error::NONE;
783 }
784
setLayerZOrder(Display display,Layer layer,uint32_t z)785 Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
786 std::lock_guard<std::mutex> guard(mutex_);
787 auto display_ptr = FindDisplay(display);
788 if (!display_ptr)
789 return Error::BAD_DISPLAY;
790
791 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
792 if (!hwc_layer)
793 return Error::BAD_LAYER;
794
795 hwc_layer->info.z_order = z;
796
797 return Error::NONE;
798 }
799
setLayerInfo(Display display,Layer layer,uint32_t type,uint32_t appId)800 Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
801 uint32_t appId) {
802 std::lock_guard<std::mutex> guard(mutex_);
803 auto display_ptr = FindDisplay(display);
804 if (!display_ptr)
805 return Error::BAD_DISPLAY;
806
807 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
808 if (!hwc_layer)
809 return Error::BAD_LAYER;
810
811 hwc_layer->info.type = type;
812 hwc_layer->info.app_id = appId;
813
814 return Error::NONE;
815 }
816
setClientTargetMetadata(Display display,const IVrComposerClient::BufferMetadata & metadata)817 Error VrHwc::setClientTargetMetadata(
818 Display display, const IVrComposerClient::BufferMetadata& metadata) {
819 std::lock_guard<std::mutex> guard(mutex_);
820 auto display_ptr = FindDisplay(display);
821 if (!display_ptr)
822 return Error::BAD_DISPLAY;
823
824 display_ptr->SetClientTargetMetadata(metadata);
825
826 return Error::NONE;
827 }
828
setLayerBufferMetadata(Display display,Layer layer,const IVrComposerClient::BufferMetadata & metadata)829 Error VrHwc::setLayerBufferMetadata(
830 Display display, Layer layer,
831 const IVrComposerClient::BufferMetadata& metadata) {
832 std::lock_guard<std::mutex> guard(mutex_);
833 auto display_ptr = FindDisplay(display);
834 if (!display_ptr)
835 return Error::BAD_DISPLAY;
836
837 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
838 if (!hwc_layer)
839 return Error::BAD_LAYER;
840
841 hwc_layer->buffer_metadata = metadata;
842
843 return Error::NONE;
844 }
845
getCapabilities(getCapabilities_cb hidl_cb)846 Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
847 hidl_cb(hidl_vec<Capability>());
848 return Void();
849 }
850
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)851 Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
852 std::string result;
853
854 {
855 std::lock_guard<std::mutex> guard(mutex_);
856 result = "\nVrHwc states:\n";
857 for (const auto& pair : displays_) {
858 result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first);
859 pair.second->dumpDebugInfo(&result);
860 }
861 result += "\n";
862 }
863
864 hidl_cb(hidl_string(result));
865 return Void();
866 }
867
createClient(createClient_cb hidl_cb)868 Return<void> VrHwc::createClient(createClient_cb hidl_cb) {
869 std::lock_guard<std::mutex> guard(mutex_);
870
871 Error status = Error::NONE;
872 sp<VrComposerClient> client;
873 if (!client_.promote().get()) {
874 client = new VrComposerClient(*this);
875 } else {
876 ALOGE("Already have a client");
877 status = Error::NO_RESOURCES;
878 }
879
880 client_ = client;
881 hidl_cb(status, client);
882 return Void();
883 }
884
ForceDisplaysRefresh()885 void VrHwc::ForceDisplaysRefresh() {
886 std::lock_guard<std::mutex> guard(mutex_);
887 if (event_callback_ != nullptr) {
888 for (const auto& pair : displays_)
889 event_callback_->onRefresh(pair.first);
890 }
891 }
892
RegisterObserver(Observer * observer)893 void VrHwc::RegisterObserver(Observer* observer) {
894 std::lock_guard<std::mutex> guard(mutex_);
895 if (observer_)
896 ALOGE("Overwriting observer");
897 else
898 observer_ = observer;
899 }
900
UnregisterObserver(Observer * observer)901 void VrHwc::UnregisterObserver(Observer* observer) {
902 std::lock_guard<std::mutex> guard(mutex_);
903 if (observer != observer_)
904 ALOGE("Trying to unregister unknown observer");
905 else
906 observer_ = nullptr;
907 }
908
FindDisplay(Display display)909 HwcDisplay* VrHwc::FindDisplay(Display display) {
910 auto iter = displays_.find(display);
911 return iter == displays_.end() ? nullptr : iter->second.get();
912 }
913
dumpDebugInfo(std::string * result) const914 void HwcLayer::dumpDebugInfo(std::string* result) const {
915 if (!result) {
916 return;
917 }
918 *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\
919 cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\
920 display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n",
921 composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y,
922 info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform,
923 info.display_frame.left, info.display_frame.top, info.display_frame.right,
924 info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right,
925 info.crop.bottom, info.blend_mode);
926 *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\
927 , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride,
928 buffer_metadata.layerCount, buffer_metadata.format);
929 }
930
931 } // namespace dvr
932 } // namespace android
933