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