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