1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*
2829790261efb161bff68251b0a1baceae6610430Mekala Natarajan* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*
4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* Redistribution and use in source and binary forms, with or without
5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* modification, are permitted provided that the following conditions are
6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* met:
7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*     * Redistributions of source code must retain the above copyright
8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       notice, this list of conditions and the following disclaimer.
9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*     * Redistributions in binary form must reproduce the above
10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       copyright notice, this list of conditions and the following
11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       disclaimer in the documentation and/or other materials provided
12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       with the distribution.
13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*     * Neither the name of The Linux Foundation nor the names of its
14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       contributors may be used to endorse or promote products derived
15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*       from this software without specific prior written permission.
16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*
17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*/
29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <math.h>
31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <errno.h>
32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <gralloc_priv.h>
33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <gr.h>
34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/constants.h>
35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/rect.h>
36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/debug.h>
37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sync/sync.h>
38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <cutils/properties.h>
39f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#include <map>
40f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#include <utility>
41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "hwc_display.h"
43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "hwc_debugger.h"
44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "blit_engine_c2d.h"
45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
46f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#ifdef QTI_BSP
47f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#include <hardware/display_defs.h>
48f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#endif
49f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define __CLASS__ "HWCDisplay"
51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinnamespace sdm {
53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
541c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmedstatic void AssignLayerRegionsAddress(LayerRectArray *region, uint32_t rect_count,
551c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed                                      uint8_t **base_address) {
561c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  if (rect_count) {
571c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    region->rect = reinterpret_cast<LayerRect *>(*base_address);
581c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    for (uint32_t i = 0; i < rect_count; i++) {
591c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      region->rect[i] = LayerRect();
601c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    }
611c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    *base_address += rect_count * sizeof(LayerRect);
621c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  }
631c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  region->count = rect_count;
641c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed}
651c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed
66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void ApplyDeInterlaceAdjustment(Layer *layer) {
67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // De-interlacing adjustment
68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (layer->input_buffer->flags.interlace) {
69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f;
70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2);
71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer->src_rect.bottom = layer->src_rect.top + floorf(height);
72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinHWCDisplay::HWCDisplay(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DisplayType type,
76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                       int id, bool needs_blit)
77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), needs_blit_(needs_blit) {
78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::Init() {
81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = core_intf_->CreateDisplay(type_, this, &display_intf_);
82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Display create failed. Error = %d display_type %d event_handler %p disp_intf %p",
84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      error, type_, this, &display_intf_);
85d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int property_swap_interval = 1;
89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  HWCDebugHandler::Get()->GetProperty("debug.egl.swapinterval", &property_swap_interval);
90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (property_swap_interval == 0) {
91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    swap_interval_zero_ = true;
92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
94d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_ = new DisplayConfigVariableInfo();
95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!framebuffer_config_) {
96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGV("Failed to allocate memory for custom framebuffer config.");
97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    core_intf_->DestroyDisplay(display_intf_);
98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (needs_blit_) {
102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_engine_ = new BlitEngineC2d();
103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!blit_engine_) {
104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      DLOGI("Create Blit Engine C2D failed");
105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (blit_engine_->Init() < 0) {
107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        DLOGI("Blit Engine Init failed, Blit Composition will not be used!!");
108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete blit_engine_;
109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        blit_engine_ = NULL;
110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  current_refresh_rate_ = max_refresh_rate_;
116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
117f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_NO_3D, kS3dFormatNone));
118f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_L_R,
119f31e45897c5f3d981922222644b9778af2302474Patrick Tjin                                kS3dFormatLeftRight));
120f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_SIDE_BY_SIDE_R_L,
121f31e45897c5f3d981922222644b9778af2302474Patrick Tjin                                kS3dFormatRightLeft));
122f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  s3d_format_hwc_to_sdm_.insert(std::pair<int, LayerBufferS3DFormat>(HAL_3D_TOP_BOTTOM,
123f31e45897c5f3d981922222644b9778af2302474Patrick Tjin                                kS3dFormatTopBottom));
124f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::Deinit() {
129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = core_intf_->DestroyDisplay(display_intf_);
130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Display destroy failed. Error = %d", error);
132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1351c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  if (layer_stack_memory_.raw) {
1361c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    delete[] layer_stack_memory_.raw;
1371c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_stack_memory_.raw = NULL;
1381c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  }
139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  delete framebuffer_config_;
141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (blit_engine_) {
143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_engine_->DeInit();
144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    delete blit_engine_;
145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_engine_ = NULL;
146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::EventControl(int event, int enable) {
152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = kErrorNone;
153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (event) {
159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_EVENT_VSYNC:
160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    error = display_intf_->SetVSyncState(enable);
161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Unsupported event = %d", event);
164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (error == kErrorShutDown) {
168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      shutdown_pending_ = true;
169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return 0;
170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Failed. event = %d, enable = %d, error = %d", event, enable, error);
172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
178d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetPowerMode(int mode) {
179d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DLOGI("display = %d, mode = %d", id_, mode);
180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayState state = kStateOff;
181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  bool flush_on_error = flush_on_error_;
182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (mode) {
188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_POWER_MODE_OFF:
189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // During power off, all of the buffers are released.
190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Do not flush until a buffer is successfully submitted again.
191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_on_error = false;
192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    state = kStateOff;
193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_POWER_MODE_NORMAL:
196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    state = kStateOn;
197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    last_power_mode_ = HWC_POWER_MODE_NORMAL;
198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_POWER_MODE_DOZE:
201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    state = kStateDoze;
202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    last_power_mode_ = HWC_POWER_MODE_DOZE;
203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_POWER_MODE_DOZE_SUSPEND:
206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    state = kStateDozeSuspend;
207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    last_power_mode_ = HWC_POWER_MODE_DOZE_SUSPEND;
208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = display_intf_->SetDisplayState(state);
215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error == kErrorNone) {
216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_on_error_ = flush_on_error;
217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  } else {
218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (error == kErrorShutDown) {
219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      shutdown_pending_ = true;
220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return 0;
221d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
222d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Set state failed. Error = %d", error);
223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
228d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetDisplayConfigs(uint32_t *configs, size_t *num_configs) {
230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (*num_configs > 0) {
231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    configs[0] = 0;
232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *num_configs = 1;
233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
236d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
237d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
238d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values) {
239d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayConfigVariableInfo variable_config = *framebuffer_config_;
240d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
241d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
242d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch (attributes[i]) {
243d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HWC_DISPLAY_VSYNC_PERIOD:
2441c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      values[i] = INT32(variable_config.vsync_period_ns);
245d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      break;
246d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HWC_DISPLAY_WIDTH:
2471c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      values[i] = INT32(variable_config.x_pixels);
248d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      break;
249d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HWC_DISPLAY_HEIGHT:
2501c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      values[i] = INT32(variable_config.y_pixels);
251d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      break;
252d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HWC_DISPLAY_DPI_X:
253d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      values[i] = INT32(variable_config.x_dpi * 1000.0f);
254d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      break;
255d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HWC_DISPLAY_DPI_Y:
256d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      values[i] = INT32(variable_config.y_dpi * 1000.0f);
257d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      break;
258d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    default:
259d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      DLOGW("Spurious attribute type = %d", attributes[i]);
260d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return -EINVAL;
261d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
262d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
263d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
264d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
265d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
266d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
267d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetActiveConfig() {
268d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
269d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
270d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
271d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetActiveConfig(int index) {
272d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return -1;
273d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
274d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
275d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
276d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  dump_frame_count_ = count;
277d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  dump_frame_index_ = 0;
278d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  dump_input_layers_ = ((bit_mask_layer_type & (1 << INPUT_LAYER_DUMP)) != 0);
279d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
280d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (blit_engine_) {
281d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_engine_->SetFrameDumpConfig(count);
282d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
283d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
284d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
285d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
286d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
287d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinuint32_t HWCDisplay::GetLastPowerMode() {
288d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return last_power_mode_;
289d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
290d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
291d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
292d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const hwc_procs_t *hwc_procs = *hwc_procs_;
293d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
294d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!hwc_procs) {
295d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return kErrorParameters;
296d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
297d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
298d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  hwc_procs->vsync(hwc_procs, id_, vsync.timestamp);
299d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
300d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return kErrorNone;
301d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
302d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
303d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::Refresh() {
304d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return kErrorNotSupported;
305d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
306d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
307d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
308d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!content_list || !content_list->numHwLayers) {
309d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Invalid content list");
310d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
311d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
312d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
313d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
314d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t blit_target_count = 0;
315d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
316d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (needs_blit_ && blit_engine_) {
317d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_target_count = kMaxBlitTargetLayers;
318d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
319d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3201c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  // Allocate memory for
3211c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  //  a) total number of layers
3221c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  //  b) buffer handle for each layer
3231c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  //  c) number of visible rectangles in each layer
3241c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  //  d) number of dirty rectangles in each layer
3251c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  //  e) number of blit rectangles in each layer
3261c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  size_t required_size = (num_hw_layers + blit_target_count) *
3271c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed                         (sizeof(Layer) + sizeof(LayerBuffer));
328d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3291c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) {
330d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uint32_t num_visible_rects = 0;
331d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uint32_t num_dirty_rects = 0;
332d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
333829790261efb161bff68251b0a1baceae6610430Mekala Natarajan    if (i < num_hw_layers) {
3341c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
3351c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      num_visible_rects = UINT32(hwc_layer.visibleRegionScreen.numRects);
3361c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      num_dirty_rects = UINT32(hwc_layer.surfaceDamage.numRects);
337829790261efb161bff68251b0a1baceae6610430Mekala Natarajan    }
338d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3391c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    // visible rectangles + dirty rectangles + blit rectangle
3401c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    size_t num_rects = num_visible_rects + num_dirty_rects + blit_target_count;
3411c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    required_size += num_rects * sizeof(LayerRect);
3421c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  }
343d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3441c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  // Layer array may be large enough to hold current number of layers.
3451c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  // If not, re-allocate it now.
3461c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  if (layer_stack_memory_.size < required_size) {
3471c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    if (layer_stack_memory_.raw) {
3481c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      delete[] layer_stack_memory_.raw;
3491c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      layer_stack_memory_.size = 0;
350d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
351d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3521c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    // Allocate in multiple of kSizeSteps.
3531c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    required_size = ROUND_UP(required_size, layer_stack_memory_.kSizeSteps);
3541c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_stack_memory_.raw = new uint8_t[required_size];
3551c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    if (!layer_stack_memory_.raw) {
3561c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      return -ENOMEM;
357829790261efb161bff68251b0a1baceae6610430Mekala Natarajan    }
3581c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed
3591c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_stack_memory_.size = required_size;
360d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
361d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3621c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  // Assign memory addresses now.
3631c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  uint8_t *current_address = layer_stack_memory_.raw;
364d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3651c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  // Layer array address
3661c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  layer_stack_ = LayerStack();
3671c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  layer_stack_.layers = reinterpret_cast<Layer *>(current_address);
3681c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  layer_stack_.layer_count = UINT32(num_hw_layers + blit_target_count);
3691c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  current_address += (num_hw_layers + blit_target_count) * sizeof(Layer);
3701c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed
3711c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) {
3721c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    uint32_t num_visible_rects = 0;
3731c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    uint32_t num_dirty_rects = 0;
3741c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed
3751c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    if (i < num_hw_layers) {
3761c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
3771c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      num_visible_rects = UINT32(hwc_layer.visibleRegionScreen.numRects);
3781c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      num_dirty_rects = UINT32(hwc_layer.surfaceDamage.numRects);
3791c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    }
380d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
381d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
3821c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer = Layer();
383d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3841c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    // Layer buffer handle address
3851c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer.input_buffer = reinterpret_cast<LayerBuffer *>(current_address);
3861c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    *layer.input_buffer = LayerBuffer();
3871c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    current_address += sizeof(LayerBuffer);
388d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
3891c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    // Visible/Dirty/Blit rectangle address
3901c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    AssignLayerRegionsAddress(&layer.visible_regions, num_visible_rects, &current_address);
3911c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    AssignLayerRegionsAddress(&layer.dirty_regions, num_dirty_rects, &current_address);
3921c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    AssignLayerRegionsAddress(&layer.blit_regions, blit_target_count, &current_address);
3931c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  }
394829790261efb161bff68251b0a1baceae6610430Mekala Natarajan
3951c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  return 0;
396d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
397d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
398d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::PrepareLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
399d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
400d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
401d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerBuffer *layer_buffer = layer->input_buffer;
402d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
403d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (pvt_handle) {
404d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
4051c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->width = UINT32(pvt_handle->width);
4061c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->height = UINT32(pvt_handle->height);
407d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
408d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (SetMetaData(pvt_handle, layer) != kErrorNone) {
409d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return -EINVAL;
410d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
411d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
412d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
413d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.video_present = true;
414d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_buffer->flags.video = true;
415d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
416d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // TZ Protected Buffer - L1
417d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
418d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.secure_present = true;
419d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_buffer->flags.secure = true;
420d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
421d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Gralloc Usage Protected Buffer - L3 - which needs to be treated as Secure & avoid fallback
422d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER) {
423d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.secure_present = true;
424d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
425d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
426d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_buffer->flags.secure_display = true;
427d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
428d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
429d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // check if this is special solid_fill layer without input_buffer.
430d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (solid_fill_enable_ && pvt_handle->fd == -1) {
431d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer->flags.solid_fill = true;
432d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer->solid_fill_color = solid_fill_color_;
433d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
434d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  } else {
435d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // for FBT layer
436d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
437d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      uint32_t x_pixels;
438d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      uint32_t y_pixels;
439d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int aligned_width;
440d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int aligned_height;
441d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int usage = GRALLOC_USAGE_HW_FB;
442d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int format = HAL_PIXEL_FORMAT_RGBA_8888;
443d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int ubwc_enabled = 0;
444d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int flags = 0;
445d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
446d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (ubwc_enabled == 1) {
447d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
448d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
449d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
450d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
451d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      GetFrameBufferResolution(&x_pixels, &y_pixels);
452d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
453d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(INT(x_pixels), INT(y_pixels), format,
454d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                            usage, aligned_width, aligned_height);
4551c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      layer_buffer->width = UINT32(aligned_width);
4561c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      layer_buffer->height = UINT32(aligned_height);
457d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_buffer->format = GetSDMFormat(format, flags);
458d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
459d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
460d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
461d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
462d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
463d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
464d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::CommitLayerParams(hwc_layer_1_t *hwc_layer, Layer *layer) {
465d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer->handle);
466d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerBuffer *layer_buffer = layer->input_buffer;
467d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
468d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (pvt_handle) {
469d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_buffer->planes[0].fd = pvt_handle->fd;
470d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_buffer->planes[0].offset = pvt_handle->offset;
4711c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->planes[0].stride = UINT32(pvt_handle->width);
4721c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->size = pvt_handle->size;
473d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
474d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
475d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // if swapinterval property is set to 0 then close and reset the acquireFd
476d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (swap_interval_zero_ && hwc_layer->acquireFenceFd >= 0) {
477d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    close(hwc_layer->acquireFenceFd);
478d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer->acquireFenceFd = -1;
479d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
480d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_buffer->acquire_fence_fd = hwc_layer->acquireFenceFd;
481d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
482d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
483d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
484d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
485d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
486d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
487d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
488d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
489d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
490d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  use_blit_comp_ = false;
491d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  metadata_refresh_rate_ = 0;
492d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_rect_ = LayerRect();
493d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
494d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Configure each layer
495d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (size_t i = 0; i < num_hw_layers; i++) {
496d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
497d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
498d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
499d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
500d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int ret = PrepareLayerParams(&content_list->hwLayers[i], &layer_stack_.layers[i]);
501d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
502d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ret != kErrorNone) {
503d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return ret;
504d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
505d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
506f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
507f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    layer.flags.solid_fill = (hwc_layer.flags & kDimLayer) || solid_fill_enable_;
508f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    if (layer.flags.skip || layer.flags.solid_fill) {
509f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      layer.dirty_regions.count = 0;
510f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    }
511f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
512d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_rect_t scaled_display_frame = hwc_layer.displayFrame;
513d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ScaleDisplayFrame(&scaled_display_frame);
514d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ApplyScanAdjustment(&scaled_display_frame);
515d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
516d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    SetRect(scaled_display_frame, &layer.dst_rect);
517d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    SetRect(hwc_layer.sourceCropf, &layer.src_rect);
518d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ApplyDeInterlaceAdjustment(&layer);
519d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
520d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (uint32_t j = 0; j < layer.visible_regions.count; j++) {
521d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      SetRect(hwc_layer.visibleRegionScreen.rects[j], &layer.visible_regions.rect[j]);
522d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
523d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (uint32_t j = 0; j < layer.dirty_regions.count; j++) {
524d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      SetRect(hwc_layer.surfaceDamage.rects[j], &layer.dirty_regions.rect[j]);
525d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
526d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    SetComposition(hwc_layer.compositionType, &layer.composition);
527d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
528d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer.compositionType != HWC_FRAMEBUFFER_TARGET) {
529d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      display_rect_ = Union(display_rect_, layer.dst_rect);
530d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
531d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
532d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
533d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // For dim layers, SurfaceFlinger
534d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - converts planeAlpha to per pixel alpha,
535d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - sets RGB color to 000,
536d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - sets planeAlpha to 0xff,
537d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - blending to Premultiplied.
538d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // This can be achieved at hardware by
539d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - solid fill ARGB to 0xff000000,
540d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - incoming planeAlpha,
541d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    //    - blending to Coverage.
542d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer.flags & kDimLayer) {
543d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.input_buffer->format = kFormatARGB8888;
544d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.solid_fill_color = 0xff000000;
545d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      SetBlending(HWC_BLENDING_COVERAGE, &layer.blending);
546d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
547d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      SetBlending(hwc_layer.blending, &layer.blending);
548d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      LayerTransform &layer_transform = layer.transform;
549d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      uint32_t &hwc_transform = hwc_layer.transform;
550d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_transform.flip_horizontal = ((hwc_transform & HWC_TRANSFORM_FLIP_H) > 0);
551d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_transform.flip_vertical = ((hwc_transform & HWC_TRANSFORM_FLIP_V) > 0);
552d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_transform.rotation = ((hwc_transform & HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f);
553d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
554d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
555d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // TODO(user): Remove below block.
556d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // For solid fill, only dest rect need to be specified.
557d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.flags.solid_fill) {
558d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      LayerBuffer *input_buffer = layer.input_buffer;
5591c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      input_buffer->width = UINT32(layer.dst_rect.right - layer.dst_rect.left);
5601c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      input_buffer->height = UINT32(layer.dst_rect.bottom - layer.dst_rect.top);
561d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.src_rect.left = 0;
562d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.src_rect.top = 0;
563d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.src_rect.right = input_buffer->width;
564d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.src_rect.bottom = input_buffer->height;
565d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
566d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
567d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer.plane_alpha = hwc_layer.planeAlpha;
568d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer.flags.cursor = ((hwc_layer.flags & HWC_IS_CURSOR_LAYER) > 0);
569d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer.flags.updating = true;
570d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
571d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (num_hw_layers <= kMaxLayerCount) {
5721c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed      layer.flags.updating = IsLayerUpdating(content_list, INT32(i));
573d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
574f31e45897c5f3d981922222644b9778af2302474Patrick Tjin#ifdef QTI_BSP
575d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
576d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.animating = true;
577d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
578d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#endif
579d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.flags.skip) {
580d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.skip_present = true;
581d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
582d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
583d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.flags.cursor) {
584d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.flags.cursor_present = true;
585d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
586d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
587d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.frame_rate > metadata_refresh_rate_) {
588d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      metadata_refresh_rate_ = SanitizeRefreshRate(layer.frame_rate);
589d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
590d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer.frame_rate = current_refresh_rate_;
591d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
592829790261efb161bff68251b0a1baceae6610430Mekala Natarajan
593829790261efb161bff68251b0a1baceae6610430Mekala Natarajan    layer.input_buffer->buffer_id = reinterpret_cast<uint64_t>(hwc_layer.handle);
594d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
595d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
596d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Prepare the Blit Target
597d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (blit_engine_) {
598d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int ret = blit_engine_->Prepare(&layer_stack_);
599d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ret) {
600d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // Blit engine cannot handle this layer stack, hence set the layer stack
601d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // count to num_hw_layers
602d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.layer_count -= kMaxBlitTargetLayers;
603d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
604d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      use_blit_comp_ = true;
605d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
606d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
607d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
608d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Configure layer stack
609d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_.flags.geometry_changed = ((content_list->flags & HWC_GEOMETRY_CHANGED) > 0);
610d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
611d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
612d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
613d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
614d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
615d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
616d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
617d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
618d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
619d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
620d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
621d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!skip_prepare_) {
622d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DisplayError error = display_intf_->Prepare(&layer_stack_);
623d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (error != kErrorNone) {
624d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (error == kErrorShutDown) {
625d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        shutdown_pending_ = true;
626d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      } else if (error != kErrorPermission) {
627d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        DLOGE("Prepare failed. Error = %d", error);
628d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
629d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // so that previous buffer and fences are released, and override the error.
630d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flush_ = true;
631d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
632d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
633d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return 0;
634d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
635d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  } else {
636d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Skip is not set
637d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    MarkLayersForGPUBypass(content_list);
638d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    skip_prepare_ = false;
639d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGI("SecureDisplay %s, Skip Prepare/Commit and Flush", secure_display_active_ ? "Starting" :
640d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          "Stopping");
641d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_ = true;
642d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
643d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
644d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // If current draw cycle has different set of layers updating in comparison to previous cycle,
645d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // cache content using GPU again.
646d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // If set of updating layers remains same, use cached buffer and replace layers marked for GPU
647d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // composition with SDE so that SurfaceFlinger does not compose them. Set cache inuse here.
648d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  bool needs_fb_refresh = NeedsFrameBufferRefresh(content_list);
649d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_cache_.in_use = false;
650d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
651d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (size_t i = 0; i < num_hw_layers; i++) {
652d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
653d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
654d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    LayerComposition composition = layer.composition;
655d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
656d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
657d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        (composition == kCompositionBlit)) {
658d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      hwc_layer.hints |= HWC_HINT_CLEAR_FB;
659d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
660d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
661d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!needs_fb_refresh && composition == kCompositionGPU) {
662d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      composition = kCompositionSDE;
663d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_cache_.in_use = true;
664d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
665d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    SetComposition(composition, &hwc_layer.compositionType);
666d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
667d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
668d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  CacheLayerStackInfo(content_list);
669d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
670d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
671d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
672d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
673d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::CommitLayerStack(hwc_display_contents_1_t *content_list) {
674d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!content_list || !content_list->numHwLayers) {
675d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Invalid content list");
676d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
677d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
678d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
679d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
680d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
681d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
682d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
683d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int status = 0;
684d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
685d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
686d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
687d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DumpInputBuffers(content_list);
688d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
689d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!flush_) {
690d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (size_t i = 0; i < num_hw_layers; i++) {
691d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      CommitLayerParams(&content_list->hwLayers[i], &layer_stack_.layers[i]);
692d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
693d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
694d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (use_blit_comp_) {
695d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      status = blit_engine_->PreCommit(content_list, &layer_stack_);
696d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (status == 0) {
697d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = blit_engine_->Commit(content_list, &layer_stack_);
698d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (status != 0) {
699d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          DLOGE("Blit Comp Failed!");
700d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
701d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
702d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
703d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
704d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DisplayError error = kErrorUndefined;
705d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (status == 0) {
706d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      error = display_intf_->Commit(&layer_stack_);
707d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      status = 0;
708d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
709d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
710d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (error == kErrorNone) {
711d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // A commit is successfully submitted, start flushing on failure now onwards.
712d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      flush_on_error_ = true;
713d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
714d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (error == kErrorShutDown) {
715d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        shutdown_pending_ = true;
716d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
717d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      } else if (error != kErrorPermission) {
718d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        DLOGE("Commit failed. Error = %d", error);
719d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
720d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // so that previous buffer and fences are released, and override the error.
721d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flush_ = true;
722d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
723d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
724d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
725d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
726d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return status;
727d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
728d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
729d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::PostCommitLayerStack(hwc_display_contents_1_t *content_list) {
730d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
731d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int status = 0;
732d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
733d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Do no call flush on errors, if a successful buffer is never submitted.
734d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (flush_ && flush_on_error_) {
735d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    display_intf_->Flush();
736d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
737d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
738d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Set the release fence fd to the blit engine
739d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (use_blit_comp_ && blit_engine_->BlitActive()) {
740d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    blit_engine_->PostCommit(&layer_stack_);
741d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
742d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
743d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (size_t i = 0; i < num_hw_layers; i++) {
744d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
745d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
746d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
747d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
748d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!flush_) {
749d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // If swapinterval property is set to 0 or for single buffer layers, do not update f/w
750d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // release fences and discard fences from driver
751d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (swap_interval_zero_ || layer.flags.single_buffer) {
752d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        hwc_layer.releaseFenceFd = -1;
753d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        close(layer_buffer->release_fence_fd);
754d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        layer_buffer->release_fence_fd = -1;
755d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      } else if (layer.composition != kCompositionGPU) {
756d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
757d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
758d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
759d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // During animation on external/virtual display, SDM will use the cached
760d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // framebuffer layer throughout animation and do not allow framework to do eglswapbuffer on
761d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // framebuffer target. So graphics doesn't close the release fence fd of framebuffer target,
762d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // Hence close the release fencefd of framebuffer target here.
763d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (layer.composition == kCompositionGPUTarget && layer_stack_cache_.animating) {
764d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        close(hwc_layer.releaseFenceFd);
765d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        hwc_layer.releaseFenceFd = -1;
766d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
767d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
768d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
769d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer.acquireFenceFd >= 0) {
770d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      close(hwc_layer.acquireFenceFd);
771d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      hwc_layer.acquireFenceFd = -1;
772d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
773d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
774d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
775d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!flush_) {
776d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_stack_cache_.animating = layer_stack_.flags.animating;
777d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
778d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // if swapinterval property is set to 0 then close and reset the list retire fence
779d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (swap_interval_zero_) {
780d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      close(layer_stack_.retire_fence_fd);
781d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      layer_stack_.retire_fence_fd = -1;
782d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
783d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    content_list->retireFenceFd = layer_stack_.retire_fence_fd;
784d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
785d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (dump_frame_count_) {
786d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      dump_frame_count_--;
787d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      dump_frame_index_++;
788d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
789d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
790d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
791d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  flush_ = false;
792d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
793d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return status;
794d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
795d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
796d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
797d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinbool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
798d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t layer_count = layer_stack_.layer_count;
799d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
800f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  // Handle ongoing animation and end here, start is handled below
801d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (layer_stack_cache_.animating) {
802f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      if (!layer_stack_.flags.animating) {
803f31e45897c5f3d981922222644b9778af2302474Patrick Tjin        // Animation is ending.
804f31e45897c5f3d981922222644b9778af2302474Patrick Tjin        return true;
805f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      } else {
806f31e45897c5f3d981922222644b9778af2302474Patrick Tjin        // Animation is going on.
807f31e45897c5f3d981922222644b9778af2302474Patrick Tjin        return false;
808f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      }
809d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
810d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
811d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Frame buffer needs to be refreshed for the following reasons:
812d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // 1. Any layer is marked skip in the current layer stack.
813d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // 2. Any layer is added/removed/layer properties changes in the current layer stack.
814d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // 3. Any layer handle is changed and it is marked for GPU composition
815d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // 4. Any layer's current composition is different from previous composition.
816d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (layer_stack_.flags.skip_present || layer_stack_.flags.geometry_changed) {
817d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return true;
818d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
819d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
820d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (uint32_t i = 0; i < layer_count; i++) {
821d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
822d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    LayerCache &layer_cache = layer_stack_cache_.layer_cache[i];
823d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
824f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    // need FB refresh for s3d case
825f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    if (layer.input_buffer->s3d_format != kS3dFormatNone) {
826f31e45897c5f3d981922222644b9778af2302474Patrick Tjin        return true;
827f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    }
828f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
829d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.composition == kCompositionGPUTarget) {
830d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      continue;
831d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
832d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
833d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer_cache.composition != layer.composition) {
834d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return true;
835d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
836d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
8371c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    if ((layer.composition == kCompositionGPU) && IsLayerUpdating(content_list, INT32(i))) {
838d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return true;
839d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
840d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
841d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
842d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return false;
843d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
844d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
845829790261efb161bff68251b0a1baceae6610430Mekala Natarajanbool HWCDisplay::IsLayerUpdating(hwc_display_contents_1_t *content_list, int layer_index) {
846829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  hwc_layer_1_t &hwc_layer = content_list->hwLayers[layer_index];
847829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  LayerCache &layer_cache = layer_stack_cache_.layer_cache[layer_index];
848829790261efb161bff68251b0a1baceae6610430Mekala Natarajan
849d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
850d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const MetaData_t *meta_data = pvt_handle ?
851d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata) : NULL;
852d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
853829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  // Layer should be considered updating if
854829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  //   a) layer is in single buffer mode, or
855829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  //   b) layer handle has changed, or
856829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  //   c) layer plane alpha has changed, or
857829790261efb161bff68251b0a1baceae6610430Mekala Natarajan  //   d) layer stack geometry has changed
858d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return ((meta_data && (meta_data->operation & SET_SINGLE_BUFFER_MODE) &&
859829790261efb161bff68251b0a1baceae6610430Mekala Natarajan              meta_data->isSingleBufferMode) ||
860d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          (layer_cache.handle != hwc_layer.handle) ||
861829790261efb161bff68251b0a1baceae6610430Mekala Natarajan          (layer_cache.plane_alpha != hwc_layer.planeAlpha) ||
862829790261efb161bff68251b0a1baceae6610430Mekala Natarajan          (content_list->flags & HWC_GEOMETRY_CHANGED));
863d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
864d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
865d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
866d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t layer_count = layer_stack_.layer_count;
867d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
868f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  if (layer_count > kMaxLayerCount || layer_stack_.flags.animating) {
869d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ResetLayerCacheStack();
870d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
871d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
872d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
873d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (uint32_t i = 0; i < layer_count; i++) {
874d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
875d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.composition == kCompositionGPUTarget ||
876d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        layer.composition == kCompositionBlitTarget) {
877d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      continue;
878d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
879d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
880d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    LayerCache &layer_cache = layer_stack_cache_.layer_cache[i];
881d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_cache.handle = content_list->hwLayers[i].handle;
882d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_cache.plane_alpha = content_list->hwLayers[i].planeAlpha;
883d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_cache.composition = layer.composition;
884d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
885d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
886d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_cache_.layer_count = layer_count;
887d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
888d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
889d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetRect(const hwc_rect_t &source, LayerRect *target) {
890d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->left = FLOAT(source.left);
891d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->top = FLOAT(source.top);
892d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->right = FLOAT(source.right);
893d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->bottom = FLOAT(source.bottom);
894d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
895d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
896d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetRect(const hwc_frect_t &source, LayerRect *target) {
897d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->left = floorf(source.left);
898d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->top = floorf(source.top);
899d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->right = ceilf(source.right);
900d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  target->bottom = ceilf(source.bottom);
901d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
902d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
903d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetComposition(const int32_t &source, LayerComposition *target) {
904d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
905d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_FRAMEBUFFER_TARGET:  *target = kCompositionGPUTarget;  break;
906d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:                      *target = kCompositionGPU;        break;
907d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
908d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
909d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
910d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetComposition(const LayerComposition &source, int32_t *target) {
911d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
912d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kCompositionGPUTarget:   *target = HWC_FRAMEBUFFER_TARGET; break;
913d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kCompositionGPU:         *target = HWC_FRAMEBUFFER;        break;
914d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kCompositionHWCursor:    *target = HWC_CURSOR_OVERLAY;     break;
915d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:                      *target = HWC_OVERLAY;            break;
916d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
917d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
918d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
919d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetBlending(const int32_t &source, LayerBlending *target) {
920d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
921d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_BLENDING_PREMULT:    *target = kBlendingPremultiplied;   break;
922d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HWC_BLENDING_COVERAGE:   *target = kBlendingCoverage;        break;
923d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:                      *target = kBlendingOpaque;          break;
924d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
925d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
926d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
927d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetIdleTimeoutMs(uint32_t timeout_ms) {
928d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return;
929d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
930d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
931d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
932d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = kErrorNone;
933d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
934d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (display_intf_) {
935d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    error = display_intf_->SetMaxMixerStages(max_mixer_stages);
936d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
937d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
938d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return error;
939d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
940d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
941d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::ControlPartialUpdate(bool enable, uint32_t *pending) {
942d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = kErrorNone;
943d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
944d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (display_intf_) {
945d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    error = display_intf_->ControlPartialUpdate(enable, pending);
946d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
947d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
948d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return error;
949d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
950d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
951d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinLayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
952d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerBufferFormat format = kFormatInvalid;
953d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
954d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch (source) {
9551c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_RGBA_8888:           format = kFormatRGBA8888Ubwc;            break;
9561c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_RGBX_8888:           format = kFormatRGBX8888Ubwc;            break;
9571c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_BGR_565:             format = kFormatBGR565Ubwc;              break;
958d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
959d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
9601c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:     format = kFormatYCbCr420SPVenusUbwc;     break;
9611c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_RGBA_1010102:        format = kFormatRGBA1010102Ubwc;         break;
9621c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_RGBX_1010102:        format = kFormatRGBX1010102Ubwc;         break;
9631c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: format = kFormatYCbCr420TP10Ubwc;        break;
964d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    default:
965d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      DLOGE("Unsupported format type for UBWC %d", source);
966d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return kFormatInvalid;
967d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
968d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return format;
969d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
970d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
971d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
972d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_8888:                format = kFormatRGBA8888;                 break;
973d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_5551:                format = kFormatRGBA5551;                 break;
974d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_4444:                format = kFormatRGBA4444;                 break;
975d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_BGRA_8888:                format = kFormatBGRA8888;                 break;
976d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBX_8888:                format = kFormatRGBX8888;                 break;
977d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_BGRX_8888:                format = kFormatBGRX8888;                 break;
978d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGB_888:                  format = kFormatRGB888;                   break;
979d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGB_565:                  format = kFormatRGB565;                   break;
980d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_BGR_565:                  format = kFormatBGR565;                   break;
981d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
982d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:       format = kFormatYCbCr420SemiPlanarVenus;  break;
983f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:       format = kFormatYCrCb420SemiPlanarVenus;  break;
984d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:  format = kFormatYCbCr420SPVenusUbwc;      break;
985d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YV12:                     format = kFormatYCrCb420PlanarStride16;   break;
986d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_420_SP:             format = kFormatYCrCb420SemiPlanar;       break;
987d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP:             format = kFormatYCbCr420SemiPlanar;       break;
988d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_422_SP:             format = kFormatYCbCr422H2V1SemiPlanar;   break;
989d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_422_I:              format = kFormatYCbCr422H2V1Packed;       break;
9901c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_RGBA_1010102:             format = kFormatRGBA1010102;              break;
9911c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_ARGB_2101010:             format = kFormatARGB2101010;              break;
9921c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_RGBX_1010102:             format = kFormatRGBX1010102;              break;
9931c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_XRGB_2101010:             format = kFormatXRGB2101010;              break;
9941c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_BGRA_1010102:             format = kFormatBGRA1010102;              break;
9951c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_ABGR_2101010:             format = kFormatABGR2101010;              break;
9961c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_BGRX_1010102:             format = kFormatBGRX1010102;              break;
9971c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_XBGR_2101010:             format = kFormatXBGR2101010;              break;
9981c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_YCbCr_420_P010:           format = kFormatYCbCr420P010;             break;
9991c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:      format = kFormatYCbCr420TP10Ubwc;         break;
1000d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1001d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Unsupported format type = %d", source);
1002d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return kFormatInvalid;
1003d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1004d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1005d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return format;
1006d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1007d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1008d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::DumpInputBuffers(hwc_display_contents_1_t *content_list) {
1009d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  size_t num_hw_layers = content_list->numHwLayers;
1010d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  char dir_path[PATH_MAX];
1011d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1012d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
1013d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1014d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1015d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1016d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  snprintf(dir_path, sizeof(dir_path), "/data/misc/display/frame_dump_%s", GetDisplayString());
1017d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1018d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
1019d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
1020d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1021d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1022d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1023d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // if directory exists already, need to explicitly change the permission.
1024d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
1025d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Failed to change permissions on %s directory", dir_path);
1026d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1027d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1028d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1029d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (uint32_t i = 0; i < num_hw_layers; i++) {
1030d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
1031d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
1032d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1033d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (hwc_layer.acquireFenceFd >= 0) {
1034d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      int error = sync_wait(hwc_layer.acquireFenceFd, 1000);
1035d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (error < 0) {
1036d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
1037d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return;
1038d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
1039d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1040d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1041d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (pvt_handle && pvt_handle->base) {
1042d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      char dump_file_name[PATH_MAX];
1043d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      size_t result = 0;
1044d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1045d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
1046d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin               dir_path, i, pvt_handle->width, pvt_handle->height,
1047d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin               GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
1048d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1049d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      FILE* fp = fopen(dump_file_name, "w+");
1050d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      if (fp) {
1051d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
1052d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        fclose(fp);
1053d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      }
1054d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1055d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
1056d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1057d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1058d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1059d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1060d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinconst char *HWCDisplay::GetHALPixelFormatString(int format) {
1061d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (format) {
1062d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_8888:
1063d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGBA_8888";
1064d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBX_8888:
1065d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGBX_8888";
1066d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGB_888:
1067d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGB_888";
1068d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGB_565:
1069d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGB_565";
1070d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_BGR_565:
1071d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "BGR_565";
1072d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_BGRA_8888:
1073d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "BGRA_8888";
1074d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_5551:
1075d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGBA_5551";
1076d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RGBA_4444:
1077d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RGBA_4444";
1078d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YV12:
1079d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YV12";
1080d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1081d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_422_SP_NV16";
1082d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1083d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCrCb_420_SP_NV21";
1084d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_422_I:
1085d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_422_I_YUY2";
1086d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_422_I:
1087d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCrCb_422_I_YVYU";
1088d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1089d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "NV12_ENCODEABLE";
1090d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1091d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_420_SP_TILED_TILE_4x2";
1092d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1093d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_420_SP";
1094d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1095d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCrCb_420_SP_ADRENO";
1096d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1097d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCrCb_422_SP";
1098d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_R_8:
1099d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "R_8";
1100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_RG_88:
1101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "RG_88";
1102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_INTERLACE:
1103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "INTERLACE";
1104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_420_SP_VENUS";
1106f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1107f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    return "YCrCb_420_SP_VENUS";
1108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "YCbCr_420_SP_VENUS_UBWC";
11101c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_RGBA_1010102:
11111c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "RGBA_1010102";
11121c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_ARGB_2101010:
11131c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "ARGB_2101010";
11141c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_RGBX_1010102:
11151c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "RGBX_1010102";
11161c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_XRGB_2101010:
11171c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "XRGB_2101010";
11181c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_BGRA_1010102:
11191c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "BGRA_1010102";
11201c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_ABGR_2101010:
11211c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "ABGR_2101010";
11221c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_BGRX_1010102:
11231c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "BGRX_1010102";
11241c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_XBGR_2101010:
11251c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "XBGR_2101010";
11261c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_YCbCr_420_P010:
11271c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "YCbCr_420_P010";
11281c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
11291c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    return "YCbCr_420_TP10_UBWC";
1130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "Unknown pixel format";
1132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinconst char *HWCDisplay::GetDisplayString() {
1136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (type_) {
1137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kPrimary:
1138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "primary";
1139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kHDMI:
1140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "hdmi";
1141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kVirtual:
1142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "virtual";
1143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return "invalid";
1145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
1149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (x_pixels <= 0 || y_pixels <= 0) {
1150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGV("Unsupported config: x_pixels=%d, y_pixels=%d", x_pixels, y_pixels);
1151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (framebuffer_config_->x_pixels == x_pixels && framebuffer_config_->y_pixels == y_pixels) {
1155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
1156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayConfigVariableInfo active_config;
1159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t active_config_index = 0;
1160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_intf_->GetActiveConfig(&active_config_index);
1161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
1162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGV("GetConfig variable info failed. Error = %d", error);
1164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (active_config.x_pixels <= 0 || active_config.y_pixels <= 0) {
1168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGV("Invalid panel resolution (%dx%d)", active_config.x_pixels, active_config.y_pixels);
1169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Create rects to represent the new source and destination crops
1173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerRect crop = LayerRect(0, 0, FLOAT(x_pixels), FLOAT(y_pixels));
1174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerRect dst = LayerRect(0, 0, FLOAT(active_config.x_pixels), FLOAT(active_config.y_pixels));
1175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  // Set rotate90 to false since this is taken care of during regular composition.
1176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  bool rotate90 = false;
1177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  error = display_intf_->IsScalingValid(crop, dst, rotate90);
1178d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1179d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGV("Unsupported resolution: (%dx%d)", x_pixels, y_pixels);
1180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_->x_pixels = x_pixels;
1184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_->y_pixels = y_pixels;
1185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_->vsync_period_ns = active_config.vsync_period_ns;
1186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_->x_dpi = active_config.x_dpi;
1187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  framebuffer_config_->y_dpi = active_config.y_dpi;
1188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DLOGI("New framebuffer resolution (%dx%d)", framebuffer_config_->x_pixels,
1190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        framebuffer_config_->y_pixels);
1191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
1193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  *x_pixels = framebuffer_config_->x_pixels;
1197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  *y_pixels = framebuffer_config_->y_pixels;
1198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::ScaleDisplayFrame(hwc_rect_t *display_frame) {
1201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!IsFrameBufferScaled()) {
1202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t active_config_index = 0;
1206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_intf_->GetActiveConfig(&active_config_index);
1207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayConfigVariableInfo active_config;
1208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
1209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("GetConfig variable info failed. Error = %d", error);
1211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float custom_x_pixels = FLOAT(framebuffer_config_->x_pixels);
1215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float custom_y_pixels = FLOAT(framebuffer_config_->y_pixels);
1216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float active_x_pixels = FLOAT(active_config.x_pixels);
1217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float active_y_pixels = FLOAT(active_config.y_pixels);
1218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float x_pixels_ratio = active_x_pixels / custom_x_pixels;
1219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float y_pixels_ratio = active_y_pixels / custom_y_pixels;
1220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float layer_width = FLOAT(display_frame->right - display_frame->left);
1221d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  float layer_height = FLOAT(display_frame->bottom - display_frame->top);
1222d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_frame->left = INT(x_pixels_ratio * FLOAT(display_frame->left));
1224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_frame->top = INT(y_pixels_ratio * FLOAT(display_frame->top));
1225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_frame->right = INT(FLOAT(display_frame->left) + layer_width * x_pixels_ratio);
1226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_frame->bottom = INT(FLOAT(display_frame->top) + layer_height * y_pixels_ratio);
1227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1228d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinbool HWCDisplay::IsFrameBufferScaled() {
1230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (framebuffer_config_->x_pixels == 0 || framebuffer_config_->y_pixels == 0) {
1231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return false;
1232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t panel_x_pixels = 0;
1234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t panel_y_pixels = 0;
1235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  GetPanelResolution(&panel_x_pixels, &panel_y_pixels);
1236d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return (framebuffer_config_->x_pixels != panel_x_pixels) ||
1237d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          (framebuffer_config_->y_pixels != panel_y_pixels);
1238d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1239d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1240d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::GetPanelResolution(uint32_t *x_pixels, uint32_t *y_pixels) {
1241d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayConfigVariableInfo active_config;
1242d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t active_config_index = 0;
1243d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_intf_->GetActiveConfig(&active_config_index);
1244d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = display_intf_->GetConfig(active_config_index, &active_config);
1245d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1246d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("GetConfig variable info failed. Error = %d", error);
1247d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return;
1248d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1249d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  *x_pixels = active_config.x_pixels;
1250d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  *y_pixels = active_config.y_pixels;
1251d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1252d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1253d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetDisplayStatus(uint32_t display_status) {
1254d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int status = 0;
1255f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  const hwc_procs_t *hwc_procs = *hwc_procs_;
1256d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1257d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (display_status) {
1258d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kDisplayStatusResume:
1259d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    display_paused_ = false;
1260d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kDisplayStatusOnline:
1261d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = SetPowerMode(HWC_POWER_MODE_NORMAL);
1262d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
1263d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kDisplayStatusPause:
1264d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    display_paused_ = true;
1265d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case kDisplayStatusOffline:
1266d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = SetPowerMode(HWC_POWER_MODE_OFF);
1267d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    break;
1268d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1269d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGW("Invalid display status %d", display_status);
1270d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1271d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1272d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1273f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  if (display_status == kDisplayStatusResume ||
1274f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      display_status == kDisplayStatusPause) {
1275f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    hwc_procs->invalidate(hwc_procs);
1276f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  }
1277f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
1278d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return status;
1279d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1280d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1281d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetCursorPosition(int x, int y) {
1282d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = kErrorNone;
1283d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1284d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (shutdown_pending_) {
1285d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
1286d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1287d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1288d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  error = display_intf_->SetCursorPosition(x, y);
1289d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1290d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (error == kErrorShutDown) {
1291d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      shutdown_pending_ = true;
1292d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return 0;
1293d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1294d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Failed for x = %d y = %d, Error = %d", x, y, error);
1295d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -1;
1296d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1297d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1298d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
1299d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1300d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1301d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
1302d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DisplayError error = display_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
1303d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (error != kErrorNone) {
1304d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Failed. Error = %d", error);
1305d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -1;
1306d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1307d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1308d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
1309d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1310d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1311d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::MarkLayersForGPUBypass(hwc_display_contents_1_t *content_list) {
1312d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (size_t i = 0 ; i < (content_list->numHwLayers - 1); i++) {
1313d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    hwc_layer_1_t *layer = &content_list->hwLayers[i];
1314d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer->compositionType = HWC_OVERLAY;
1315d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1316d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1317d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1318d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinuint32_t HWCDisplay::RoundToStandardFPS(uint32_t fps) {
1319d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  static const uint32_t standard_fps[4] = {30, 24, 48, 60};
1320d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1321d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int count = INT(sizeof(standard_fps) / sizeof(standard_fps[0]));
1322d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (int i = 0; i < count; i++) {
1323d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if ((standard_fps[i] - fps) < 2) {
1324d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // Most likely used for video, the fps can fluctuate
1325d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      // Ex: b/w 29 and 30 for 30 fps clip
1326d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return standard_fps[i];
1327d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1328d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1329d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1330d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return fps;
1331d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1332d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1333d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
1334d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1335d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1336d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::SetCSC(ColorSpace_t source, LayerCSC *target) {
1337d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
1338d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case ITU_R_601:       *target = kCSCLimitedRange601;   break;
1339d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case ITU_R_601_FR:    *target = kCSCFullRange601;      break;
1340d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case ITU_R_709:       *target = kCSCLimitedRange709;   break;
1341d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1342d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Unsupported CSC: %d", source);
1343d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return kErrorNotSupported;
1344d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1345d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1346d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return kErrorNone;
1347d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1348d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1349d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::SetIGC(IGC_t source, LayerIGC *target) {
1350d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  switch (source) {
1351d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case IGC_NotSpecified:    *target = kIGCNotSpecified; break;
1352d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  case IGC_sRGB:            *target = kIGCsRGB;   break;
1353d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  default:
1354d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    DLOGE("Unsupported IGC: %d", source);
1355d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return kErrorNotSupported;
1356d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1357d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1358d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return kErrorNone;
1359d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1360d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1361d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWCDisplay::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
1362d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
1363d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  LayerBuffer *layer_buffer = layer->input_buffer;
1364d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1365d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!meta_data) {
1366d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return kErrorNone;
1367d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1368d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1369d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & UPDATE_COLOR_SPACE) {
1370d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (SetCSC(meta_data->colorSpace, &layer->csc) != kErrorNone) {
1371d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return kErrorNotSupported;
1372d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1373d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1374d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1375d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & SET_IGC) {
1376d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (SetIGC(meta_data->igc, &layer->igc) != kErrorNone) {
1377d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      return kErrorNotSupported;
1378d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1379d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1380d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1381d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & UPDATE_REFRESH_RATE) {
1382d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer->frame_rate = RoundToStandardFPS(meta_data->refreshrate);
1383d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1384d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1385d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if ((meta_data->operation & PP_PARAM_INTERLACED) && meta_data->interlaced) {
1386d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_buffer->flags.interlace = true;
1387d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1388d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1389d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & LINEAR_FORMAT) {
13901c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->format = GetSDMFormat(INT32(meta_data->linearFormat), 0);
1391d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1392d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1393d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & UPDATE_BUFFER_GEOMETRY) {
1394d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int actual_width = pvt_handle->width;
1395d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int actual_height = pvt_handle->height;
1396d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(pvt_handle, actual_width, actual_height);
13971c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->width = UINT32(actual_width);
13981c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed    layer_buffer->height = UINT32(actual_height);
1399d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1400d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1401d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (meta_data->operation & SET_SINGLE_BUFFER_MODE) {
1402d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer->flags.single_buffer = meta_data->isSingleBufferMode;
1403d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Graphics can set this operation on all types of layers including FB and set the actual value
1404d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // to 0. To protect against SET operations of 0 value, we need to do a logical OR.
1405d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_stack_.flags.single_buffered_layer_present |= meta_data->isSingleBufferMode;
1406d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1407d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1408f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  if (meta_data->operation & S3D_FORMAT) {
1409f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    std::map<int, LayerBufferS3DFormat>::iterator it =
14101c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed        s3d_format_hwc_to_sdm_.find(INT32(meta_data->s3dFormat));
1411f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    if (it != s3d_format_hwc_to_sdm_.end()) {
1412f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      layer->input_buffer->s3d_format = it->second;
1413f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    } else {
1414f31e45897c5f3d981922222644b9778af2302474Patrick Tjin      DLOGW("Invalid S3D format %d", meta_data->s3dFormat);
1415f31e45897c5f3d981922222644b9778af2302474Patrick Tjin    }
1416f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  }
1417f31e45897c5f3d981922222644b9778af2302474Patrick Tjin
1418d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return kErrorNone;
1419d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1420d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1421d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetPanelBrightness(int level) {
1422d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int ret = 0;
1423d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (display_intf_)
1424d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ret = display_intf_->SetPanelBrightness(level);
1425d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  else
1426d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ret = -EINVAL;
1427d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1428d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return ret;
1429d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1430d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1431d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetPanelBrightness(int *level) {
1432d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return display_intf_->GetPanelBrightness(level);
1433d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1434d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1435d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::ToggleScreenUpdates(bool enable) {
1436f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  const hwc_procs_t *hwc_procs = *hwc_procs_;
1437d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  display_paused_ = enable ? false : true;
1438f31e45897c5f3d981922222644b9778af2302474Patrick Tjin  hwc_procs->invalidate(hwc_procs);
1439d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
1440d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1441d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1442d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
1443d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     PPDisplayAPIPayload *out_payload,
1444d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     PPPendingParams *pending_action) {
1445d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  int ret = 0;
1446d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1447d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (display_intf_)
1448d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ret = display_intf_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
1449d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  else
1450d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ret = -EINVAL;
1451d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1452d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return ret;
1453d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1454d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1455d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetVisibleDisplayRect(hwc_rect_t* visible_rect) {
1456d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (!IsValid(display_rect_)) {
1457d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1458d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1459d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1460d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  visible_rect->left = INT(display_rect_.left);
1461d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  visible_rect->top = INT(display_rect_.top);
1462d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  visible_rect->right = INT(display_rect_.right);
1463d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  visible_rect->bottom = INT(display_rect_.bottom);
1464d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  DLOGI("Dpy = %d Visible Display Rect(%d %d %d %d)", visible_rect->left, visible_rect->top,
1465d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        visible_rect->right, visible_rect->bottom);
1466d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1467d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return 0;
1468d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1469d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1470d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::ResetLayerCacheStack() {
1471d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t layer_count = layer_stack_cache_.layer_count;
1472d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (uint32_t i = 0; i < layer_count; i++) {
1473d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    layer_stack_cache_.layer_cache[i] = LayerCache();
1474d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1475d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_cache_.layer_count = 0;
1476d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_cache_.animating = false;
1477d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  layer_stack_cache_.in_use = false;
1478d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1479d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1480d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWCDisplay::SetSecureDisplay(bool secure_display_active) {
1481d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  secure_display_active_ = secure_display_active;
1482d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return;
1483d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1484d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1485d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::SetActiveDisplayConfig(int config) {
14861c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  return display_intf_->SetActiveConfig(UINT32(config)) == kErrorNone ? 0 : -1;
1487d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1488d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1489d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
1490d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return display_intf_->GetActiveConfig(config) == kErrorNone ? 0 : -1;
1491d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1492d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1493d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetDisplayConfigCount(uint32_t *count) {
1494d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return display_intf_->GetNumVariableInfoConfigs(count) == kErrorNone ? 0 : -1;
1495d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1496d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1497d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint HWCDisplay::GetDisplayAttributesForConfig(int config, DisplayConfigVariableInfo *attributes) {
14981c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed  return display_intf_->GetConfig(UINT32(config), attributes) == kErrorNone ? 0 : -1;
1499d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1500d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1501d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinbool HWCDisplay::SingleLayerUpdating(uint32_t app_layer_count) {
1502d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t updating_count = 0;
1503d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1504d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  for (uint i = 0; i < app_layer_count; i++) {
1505d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Layer &layer = layer_stack_.layers[i];
1506d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (layer.flags.updating) {
1507d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin      updating_count++;
1508d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1509d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1510d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1511d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return (updating_count == 1);
1512d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1513d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1514d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinuint32_t HWCDisplay::SanitizeRefreshRate(uint32_t req_refresh_rate) {
1515d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  uint32_t refresh_rate = req_refresh_rate;
1516d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1517d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (refresh_rate < min_refresh_rate_) {
1518d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Pick the next multiple of request which is within the range
1519d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    refresh_rate = (((min_refresh_rate_ / refresh_rate) +
1520d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                     ((min_refresh_rate_ % refresh_rate) ? 1 : 0)) * refresh_rate);
1521d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1522d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1523d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  if (refresh_rate > max_refresh_rate_) {
1524d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    refresh_rate = max_refresh_rate_;
1525d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  }
1526d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1527d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin  return refresh_rate;
1528d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1529d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1530d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}  // namespace sdm
1531