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