1d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema/*
2d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
3d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*
4d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* Redistribution and use in source and binary forms, with or without
5d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* modification, are permitted provided that the following conditions are
6d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* met:
7d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*     * Redistributions of source code must retain the above copyright
8d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       notice, this list of conditions and the following disclaimer.
9d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*     * Redistributions in binary form must reproduce the above
10d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       copyright notice, this list of conditions and the following
11d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       disclaimer in the documentation and/or other materials provided
12d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       with the distribution.
13d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*     * Neither the name of The Linux Foundation nor the names of its
14d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       contributors may be used to endorse or promote products derived
15d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*       from this software without specific prior written permission.
16d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*
17d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*/
29d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
30d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <dlfcn.h>
31d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <powermanager/IPowerManager.h>
32d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <cutils/sockets.h>
33d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <cutils/native_handle.h>
34d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/String16.h>
35d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <binder/Parcel.h>
36d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <gralloc_priv.h>
37d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <hardware/hwcomposer.h>
38d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <hardware/hwcomposer_defs.h>
39d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <QService.h>
40d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
41d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <core/dump_interface.h>
42d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/constants.h>
43d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/debug.h>
44d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <core/buffer_allocator.h>
45d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <private/color_params.h>
46d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_buffer_allocator.h"
47d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_buffer_sync_handler.h"
48d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_session.h"
49d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_debugger.h"
50d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
51d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#define __CLASS__ "HWCColorManager"
52d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
53d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemanamespace sdm {
54d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
55d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemauint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
56d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
57d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                        ((params.color.b) & 0xff);
58d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return argb_color;
59d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
60d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
61d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
62d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             PPDisplayAPIPayload *sink) {
63d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
64d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t id(0);
65d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t size(0);
66d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
67d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  id = UINT32(in.readInt32());
68d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  size = UINT32(in.readInt32());
69d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (size > 0 && size == in.dataAvail()) {
70d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    const void *data = in.readInplace(size);
71d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
72d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
73d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    sink->size = size;
74d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    sink->payload = const_cast<uint8_t *>(temp);
75d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    *disp_id = id;
76d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
77d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("Failing size checking, size = %d", size);
78d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = -EINVAL;
79d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
80d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
81d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
82d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
83d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
84d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
85d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                               android::Parcel *out_parcel) {
86d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  out_parcel->writeInt32(INT32(data.size));
87d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (data.payload)
88d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    out_parcel->write(data.payload, data.size);
89d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
90d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
91d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCColorManager *HWCColorManager::CreateColorManager() {
92d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  HWCColorManager *color_mgr = new HWCColorManager();
93d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
94d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (color_mgr) {
95d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Load display API interface library. And retrieve color API function tables.
96d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DynLib &color_apis_lib = color_mgr->color_apis_lib_;
97d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
98d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
99d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
100d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              DISPLAY_API_INTERFACE_LIBRARY_NAME);
101d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete color_mgr;
102d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        return NULL;
103d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
104d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
105d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
106d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      delete color_mgr;
107d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return NULL;
108d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
109d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
110d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
111d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Load diagclient library and invokes its entry point to pass in display APIs.
112d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DynLib &diag_client_lib = color_mgr->diag_client_lib_;
113d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
114d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
115d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
116d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
117d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
118d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
119d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              QDCM_DIAG_CLIENT_LIBRARY_NAME);
120d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else {
121d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        // invoke Diag Client entry point to initialize.
122d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
123d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
124d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              QDCM_DIAG_CLIENT_LIBRARY_NAME);
125d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
126d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
127d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
128d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      // only QDCM Diag client failed to be loaded and system still should function.
129d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
130d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
131d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGE("Unable to create HWCColorManager");
132d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return NULL;
133d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
134d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
135d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return color_mgr;
136d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
137d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
138d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCColorManager::~HWCColorManager() {
139d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
140d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
141d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::DestroyColorManager() {
142d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_mode_mgr_) {
143d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    delete qdcm_mode_mgr_;
144d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
145d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_diag_deinit_) {
146d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    qdcm_diag_deinit_();
147d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
148d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  delete this;
149d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
150d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
151d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
152d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
153d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
154d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!qdcm_mode_mgr_) {
155d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
156d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!qdcm_mode_mgr_) {
157d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Unable to create QDCM operating mode manager.");
158d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = -EFAULT;
159d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
160d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
161d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
162d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_mode_mgr_) {
163d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
164d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
165d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
166d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
167d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
168d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
169d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemabool HWCColorManager::SolidFillLayersPrepare(hwc_display_contents_1_t **displays,
170d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             HWCDisplay *hwc_display) {
171d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
172d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
173d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
174d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
175d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
176d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
177d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
178d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // 1. shallow copy HWC_FRAMEBUFFER_TARGET layer info solid fill layer list.
179d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_layers_->hwLayers[1] = layer_list->hwLayers[layer_list->numHwLayers - 1];
180d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
181d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // 2. continue the prepare<> on solid_fill_layers.
182d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
183d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Prepare(solid_fill_layers_);  // RECT info included.
184d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
185d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // 3. Set HWC_OVERLAY to all SF layers before returning to framework.
186d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
187d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      hwc_layer_1_t *layer = &layer_list->hwLayers[i];
188d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      layer->compositionType = HWC_OVERLAY;
189d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
190d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
191d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return true;
192d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else if (!solid_fill_enable_) {
193d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
194d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
195d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
196d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return false;
197d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
198d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
199d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemabool HWCColorManager::SolidFillLayersSet(hwc_display_contents_1_t **displays,
200d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                         HWCDisplay *hwc_display) {
201d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
202d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
203d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
204d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
205d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Commit(solid_fill_layers_);
206d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
207d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // SurfaceFlinger layer stack is dropped in solid fill case and replaced with local layer stack
208d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Close acquire fence fds associated with SF layer stack
209d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Close release/retire fence fds returned along with local layer stack
210d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
211d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      int &fence_fd = layer_list->hwLayers[i].acquireFenceFd;
212d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (fence_fd >= 0) {
213d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        close(fence_fd);
214d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        fence_fd = -1;
215d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
216d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
217d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
218d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    for (size_t i = 0; i < (solid_fill_layers_->numHwLayers - 1); i++) {
219d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      int &fence_fd = solid_fill_layers_->hwLayers[i].releaseFenceFd;
220d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (fence_fd >= 0) {
221d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        close(fence_fd);
222d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        fence_fd = -1;
223d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
224d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
225d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (solid_fill_layers_->retireFenceFd >= 0) {
226d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      close(solid_fill_layers_->retireFenceFd);
227d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      solid_fill_layers_->retireFenceFd = -1;
228d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
229d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
230d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return true;
231d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
232d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
233d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return false;
234d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
235d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
236d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) {
237d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
238d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
239d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!solid_fill_layers_) {
240d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint32_t size = sizeof(hwc_display_contents_1) + kNumSolidFillLayers * sizeof(hwc_layer_1_t);
241d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint32_t primary_width = 0;
242d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint32_t primary_height = 0;
243d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
244d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->GetMixerResolution(&primary_width, &primary_height);
245d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint8_t *buf = new uint8_t[size]();
246d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // handle for solid fill layer with fd = -1.
247d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    private_handle_t *handle =
248d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI,
249d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                             HAL_PIXEL_FORMAT_RGBA_8888, INT32(primary_width),
250d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                             INT32(primary_height));
251d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
252d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!buf || !handle) {
253d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Failed to allocate memory.");
254d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (buf)
255d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete[] buf;
256d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (handle)
257d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete handle;
258d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
259d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -ENOMEM;
260d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
261d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
262d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_layers_ = reinterpret_cast<hwc_display_contents_1 *>(buf);
263d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
264d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    layer.handle = handle;
265d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
266d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
267d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_layers_->flags = HWC_GEOMETRY_CHANGED;
268d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_layers_->numHwLayers = kNumSolidFillLayers;
269d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_layers_->retireFenceFd = -1;
270d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_layers_->outbuf = NULL;
271d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_layers_->outbufAcquireFenceFd = -1;
272d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
273d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
274d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  hwc_rect_t solid_fill_rect = {
275d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      INT(solid_fill_params_.rect.x),
276d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      INT(solid_fill_params_.rect.y),
277d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      solid_fill_params_.rect.x + INT(solid_fill_params_.rect.width),
278d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      solid_fill_params_.rect.y + INT(solid_fill_params_.rect.height),
279d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  };
280d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
281d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.compositionType = HWC_FRAMEBUFFER;
282d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.blending = HWC_BLENDING_PREMULT;
283d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.sourceCropf.left = solid_fill_params_.rect.x;
284d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.sourceCropf.top = solid_fill_params_.rect.y;
285d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.sourceCropf.right = UINT32(solid_fill_params_.rect.x) + solid_fill_params_.rect.width;
286d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.sourceCropf.bottom = UINT32(solid_fill_params_.rect.y) + solid_fill_params_.rect.height;
287d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.acquireFenceFd = -1;
288d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.releaseFenceFd = -1;
289d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.flags = 0;
290d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.transform = 0;
291d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.hints = 0;
292d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.planeAlpha = 0xff;
293d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.displayFrame = solid_fill_rect;
294d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.visibleRegionScreen.numRects = 1;
295d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.visibleRegionScreen.rects = &layer.displayFrame;
296d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  layer.surfaceDamage.numRects = 0;
297d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
298d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
299d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
300d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
301d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::DestroySolidFillLayers() {
302d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (solid_fill_layers_) {
303d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
304d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint8_t *buf = reinterpret_cast<uint8_t *>(solid_fill_layers_);
305d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(layer.handle);
306d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
307d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (hnd)
308d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete hnd;
309d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
310d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (buf)
311d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete[] buf;
312d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
313d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_layers_ = NULL;
314d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
315d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
316d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
317d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
318d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
319d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
320d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
321d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (params) {
322d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
323d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
324d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_params_ = PPColorFillParams();
325d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
326d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
327d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (enable) {
328d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // will create solid fill layers for rendering if not present.
329d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = CreateSolidFillLayers(hwc_display);
330d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
331d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DestroySolidFillLayers();
332d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
333d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  solid_fill_enable_ = enable;
334d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
335d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
336d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
337d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
338d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
339d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
340d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
341d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
342d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData*>(params);
343d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
344d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (enable) {
345d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    std::memset(&buffer_info, 0x00, sizeof(buffer_info));
346d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->GetPanelResolution(&buffer_info.buffer_config.width,
347d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                    &buffer_info.buffer_config.height);
348d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
349d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      buffer_info.buffer_config.format = kFormatRGB888;
350d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
351d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      buffer_info.buffer_config.format = kFormatRGBA1010102;
352d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
353d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
354d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -EFAULT;
355d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
356d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
357d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.buffer_config.buffer_count = 1;
358d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.fd = -1;
359d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.stride = 0;
360d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.size = 0;
361d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
362d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_allocator_ = new HWCBufferAllocator();
363d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (buffer_allocator_ == NULL) {
364d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Memory allocation for buffer_allocator_ FAILED");
365d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -ENOMEM;
366d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
367d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
368d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = buffer_allocator_->AllocateBuffer(&buffer_info);
369d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (ret != 0) {
370d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Buffer allocation failed. ret: %d", ret);
371d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      delete buffer_allocator_;
372d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      buffer_allocator_ = NULL;
373d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -ENOMEM;
374d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
375d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size,
376d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                          PROT_READ|PROT_WRITE,
377d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                          MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
378d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
379d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (buffer == MAP_FAILED) {
380d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("mmap failed. err = %d", errno);
381d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer = NULL;
382d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = buffer_allocator_->FreeBuffer(&buffer_info);
383d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete buffer_allocator_;
384d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        buffer_allocator_ = NULL;
385d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        return -EFAULT;
386d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else {
387d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
388d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.aligned_width;
389d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
390d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
391d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
392d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (ret < 0) {
393d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("FrameCaptureAsync failed. ret = %d", ret);
394d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
395d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
396d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
397d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = hwc_display->GetFrameCaptureStatus();
398d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!ret) {
399d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (frame_capture_data->buffer != NULL) {
400d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
401d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          DLOGE("munmap failed. err = %d", errno);
402d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
403d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
404d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (buffer_allocator_ != NULL) {
405d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
406d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = buffer_allocator_->FreeBuffer(&buffer_info);
407d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        if (ret != 0) {
408d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          DLOGE("FreeBuffer failed. ret = %d", ret);
409d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
410d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete buffer_allocator_;
411d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        buffer_allocator_ = NULL;
412d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
413d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
414d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("GetFrameCaptureStatus failed. ret = %d", ret);
415d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
416d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
417d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
418d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
419d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
420d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) {
421d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
422d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  DisplayDetailEnhancerData de_data;
423d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
424d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
425d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (de_tuning_cfg_data->cfg_pending == true) {
426d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!de_tuning_cfg_data->cfg_en) {
427d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.enable = 0;
428d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
429d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.override_flags = kOverrideDEEnable;
430d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.enable = 1;
431d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
432d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
433d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDESharpen1;
434d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
435d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
436d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
437d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
438d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEClip;
439d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.clip = de_tuning_cfg_data->params.clip;
440d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
441d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
442d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
443d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrQuiet;
444d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
445d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
446d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
447d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
448d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrDieout;
449d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
450d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
451d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
452d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
453d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrLow;
454d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_low = de_tuning_cfg_data->params.thr_low;
455d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
456d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
457d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
458d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrHigh;
459d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_high = de_tuning_cfg_data->params.thr_high;
460d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
461d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
462d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
463d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        switch (de_tuning_cfg_data->params.quality) {
464d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualLow:
465d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityLow;
466d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
467d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualMedium:
468d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityMedium;
469d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
470d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualHigh:
471d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityHigh;
472d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
473d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualUnknown:
474d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          default:
475d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityUnknown;
476d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
477d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
478d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
479d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
480d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    err = hwc_display->SetDetailEnhancerConfig(de_data);
481d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (err) {
482d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
483d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
484d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    de_tuning_cfg_data->cfg_pending = false;
485d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
486d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return err;
487d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
488d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
489d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) {
490d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
491d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
492d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPPendingParams pending_action;
493d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPDisplayAPIPayload req_payload;
494d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
495d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  pending_action.action = kGetDetailedEnhancerData;
496d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  pending_action.params = NULL;
497d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
498d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (hwc_display) {
499d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action);
500d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!err && pending_action.action == kConfigureDetailedEnhancer) {
501d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display);
502d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
503d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
504d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return;
505d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
506d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
507d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
508d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
509d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
510d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  err = SetHWDetailedEnhancerConfig(params, hwc_display);
511d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return err;
512d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
513d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
514d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
515d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
516d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
517d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
518d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema};
519d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
520d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kSocketName = "pps";
521d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
522d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kPackageName = "colormanager";
523d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
524d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
525d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
526d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
527d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!mode_mgr) {
528d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("No memory to create HWCQDCMModeManager.");
529d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return NULL;
530d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
531d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    mode_mgr->socket_fd_ =
532d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
533d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (mode_mgr->socket_fd_ < 0) {
534d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      // it should not be disastrous and we still can grab wakelock in QDCM mode.
535d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to connect to dpps socket!");
536d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
537d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
538d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // retrieve system GPU idle timeout value for later to recover.
539d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
540d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
541d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // acquire the binder handle to Android system PowerManager for later use.
542d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    android::sp<android::IBinder> binder =
543d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        android::defaultServiceManager()->checkService(android::String16("power"));
544d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (binder == NULL) {
545d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Application can't connect to  power manager service");
546d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      delete mode_mgr;
547d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      mode_mgr = NULL;
548d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
549d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder);
550d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
551d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
552d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
553d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return mode_mgr;
554d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
555d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
556d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCQDCMModeManager::~HWCQDCMModeManager() {
557d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (socket_fd_ >= 0)
558d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ::close(socket_fd_);
559d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
560d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
561d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) {
562d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
563d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
564d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (enable) {
565d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (wakelock_token_ == NULL) {
566d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      android::sp<android::IBinder> binder = new android::BBinder();
567d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      android::status_t status = power_mgr_->acquireWakeLock(
568d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder,
569d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          android::String16(kTagName), android::String16(kPackageName));
570d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (status == android::NO_ERROR) {
571d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        wakelock_token_ = binder;
572d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
573d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
574d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
575d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (wakelock_token_ != NULL && power_mgr_ != NULL) {
576d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      power_mgr_->releaseWakeLock(wakelock_token_, 0);
577d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      wakelock_token_.clear();
578d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      wakelock_token_ = NULL;
579d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
580d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
581d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
582d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
583d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
584d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
585d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCQDCMModeManager::EnableActiveFeatures(bool enable,
586d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
587d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             bool *was_running) {
588d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
589d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  ssize_t size = 0;
590d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  char response[kSocketCMDMaxLength] = {
591d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      0,
592d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  };
593d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
594d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (socket_fd_ < 0) {
595d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("No socket connection available!");
596d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return -EFAULT;
597d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
598d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
599d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!enable) {  // if client requesting to disable it.
600d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // query CABL status, if off, no action. keep the status.
601d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
602d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (size < 0) {
603d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to send data over socket %s", ::strerror(errno));
604d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = -EFAULT;
605d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
606d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::read(socket_fd_, response, kSocketCMDMaxLength);
607d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
608d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to read data over socket %s", ::strerror(errno));
609d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
610d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
611d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        *was_running = true;
612d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
613d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
614d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
615d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (*was_running) {  // if was running, it's requested to disable it.
616d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
617d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
618d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to send data over socket %s", ::strerror(errno));
619d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
620d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
621d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
622d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {  // if was running, need enable it back.
623d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (*was_running) {
624d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
625d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
626d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to send data over socket %s", ::strerror(errno));
627d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
628d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
629d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
630d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
631d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
632d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
633d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
634d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
635d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
636d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
637d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
638d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
639d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                             &cabl_was_running_);
640d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  ret = AcquireAndroidWakeLock(enable);
641d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
642d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  // if enter QDCM mode, disable GPU fallback idle timeout.
643d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (hwc_display) {
644d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint32_t timeout = enable ? 0 : entry_timeout_;
645d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->SetIdleTimeoutMs(timeout);
646d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
647d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
648d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
649d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
650d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
651d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}  // namespace sdm
652