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 <cutils/sockets.h>
32d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <cutils/native_handle.h>
33d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/String16.h>
34d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <binder/Parcel.h>
35d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <gralloc_priv.h>
36d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <hardware/hwcomposer.h>
37d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <hardware/hwcomposer_defs.h>
38d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <QService.h>
39d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
40d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/constants.h>
41d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/debug.h>
42d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <core/buffer_allocator.h>
43d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <private/color_params.h>
44d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_buffer_allocator.h"
45d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_buffer_sync_handler.h"
46d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_session.h"
47d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_debugger.h"
48d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
49d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#define __CLASS__ "HWCColorManager"
50d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
51d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemanamespace sdm {
52d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
53d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemauint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams &params) {
54d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) |
55d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                        ((params.color.b) & 0xff);
56d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return argb_color;
57d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
58d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
59d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
60d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             PPDisplayAPIPayload *sink) {
61d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
62d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t id(0);
63d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t size(0);
64d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
65d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  id = UINT32(in.readInt32());
66d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  size = UINT32(in.readInt32());
67d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (size > 0 && size == in.dataAvail()) {
68d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    const void *data = in.readInplace(size);
69d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
70d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
71d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    sink->size = size;
72d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    sink->payload = const_cast<uint8_t *>(temp);
73d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    *disp_id = id;
74d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
75d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("Failing size checking, size = %d", size);
76d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = -EINVAL;
77d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
78d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
79d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
80d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
81d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
82d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
83d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                               android::Parcel *out_parcel) {
84d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  out_parcel->writeInt32(INT32(data.size));
85d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (data.payload)
86d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    out_parcel->write(data.payload, data.size);
87d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
88d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
89d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) {
90d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator);
91d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
92d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (color_mgr) {
93d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Load display API interface library. And retrieve color API function tables.
94d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DynLib &color_apis_lib = color_mgr->color_apis_lib_;
95d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
96d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
97d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
98d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              DISPLAY_API_INTERFACE_LIBRARY_NAME);
99d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        delete color_mgr;
100d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        return NULL;
101d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
102d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
103d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
104d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      delete color_mgr;
105d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return NULL;
106d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
107d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
108d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
109d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // Load diagclient library and invokes its entry point to pass in display APIs.
110d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DynLib &diag_client_lib = color_mgr->diag_client_lib_;
111d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
112d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
113d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
114d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
115d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                               reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
116d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
117d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              QDCM_DIAG_CLIENT_LIBRARY_NAME);
118d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else {
119d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        // invoke Diag Client entry point to initialize.
120d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
121d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
122d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema              QDCM_DIAG_CLIENT_LIBRARY_NAME);
123d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
124d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
125d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
126d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      // only QDCM Diag client failed to be loaded and system still should function.
127d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
128d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
129d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGE("Unable to create HWCColorManager");
130d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return NULL;
131d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
132d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
133d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return color_mgr;
134d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
135d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
136d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) :
137d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_allocator_(buffer_allocator) {
138d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
139d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
140d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCColorManager::~HWCColorManager() {
141d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
142d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
143d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::DestroyColorManager() {
144d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_mode_mgr_) {
145d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    delete qdcm_mode_mgr_;
146d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
147d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_diag_deinit_) {
148d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    qdcm_diag_deinit_();
149d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
150d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  delete this;
151d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
152d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
153d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
154d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
155d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
156d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!qdcm_mode_mgr_) {
157d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
158d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!qdcm_mode_mgr_) {
159d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Unable to create QDCM operating mode manager.");
160d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = -EFAULT;
161d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
162d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
163d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
164d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (qdcm_mode_mgr_) {
165d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
166d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
167d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
168d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
169d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
170d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
171d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
172d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
173d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
174d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (params) {
175d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
176d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
177d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    solid_fill_params_ = PPColorFillParams();
178d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
179d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
180d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
181d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (enable) {
182d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    LayerRect solid_fill_rect = {
183d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      FLOAT(solid_fill_params_.rect.x), FLOAT(solid_fill_params_.rect.y),
184d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      FLOAT(solid_fill_params_.rect.x) + FLOAT(solid_fill_params_.rect.width),
185d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      FLOAT(solid_fill_params_.rect.y) + FLOAT(solid_fill_params_.rect.height),
186d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    };
187d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
188d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
189d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_RECT, &solid_fill_rect);
190d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
191d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
192d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
193d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
194d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return 0;
195d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
196d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
197d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) {
198d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
199d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
200d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
201d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params);
202d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
203d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (enable) {
204d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    std::memset(&buffer_info, 0x00, sizeof(buffer_info));
205d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->GetPanelResolution(&buffer_info.buffer_config.width,
206d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                    &buffer_info.buffer_config.height);
207d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) {
208d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      buffer_info.buffer_config.format = kFormatRGB888;
209d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) {
210d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      buffer_info.buffer_config.format = kFormatRGBA1010102;
211d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
212d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format);
213d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -EFAULT;
214d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
215d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
216d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.buffer_config.buffer_count = 1;
217d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.fd = -1;
218d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.stride = 0;
219d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    buffer_info.alloc_buffer_info.size = 0;
220d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
221d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = buffer_allocator_->AllocateBuffer(&buffer_info);
222d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (ret != 0) {
223d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("Buffer allocation failed. ret: %d", ret);
224d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      return -ENOMEM;
225d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
226d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE,
227d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                          MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0);
228d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
229d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (buffer == MAP_FAILED) {
230d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("mmap failed. err = %d", errno);
231d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer = NULL;
232d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = buffer_allocator_->FreeBuffer(&buffer_info);
233d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        return -EFAULT;
234d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else {
235d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer);
236d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride;
237d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size;
238d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
239d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = hwc_display->FrameCaptureAsync(buffer_info, 1);
240d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (ret < 0) {
241d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGE("FrameCaptureAsync failed. ret = %d", ret);
242d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
243d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
244d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
245d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ret = hwc_display->GetFrameCaptureStatus();
246d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!ret) {
247d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (frame_capture_data->buffer != NULL) {
248d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) {
249d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          DLOGE("munmap failed. err = %d", errno);
250d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
251d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
252d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (buffer_allocator_ != NULL) {
253d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData));
254d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = buffer_allocator_->FreeBuffer(&buffer_info);
255d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        if (ret != 0) {
256d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          DLOGE("FreeBuffer failed. ret = %d", ret);
257d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
258d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
259d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
260d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGE("GetFrameCaptureStatus failed. ret = %d", ret);
261d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
262d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
263d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
264d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
265d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
266d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) {
267d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
268d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  DisplayDetailEnhancerData de_data;
269d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
270d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params);
271d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (de_tuning_cfg_data->cfg_pending == true) {
272d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!de_tuning_cfg_data->cfg_en) {
273d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.enable = 0;
274d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
275d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.override_flags = kOverrideDEEnable;
276d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      de_data.enable = 1;
277d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
278d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) {
279d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDESharpen1;
280d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor;
281d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
282d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
283d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) {
284d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEClip;
285d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.clip = de_tuning_cfg_data->params.clip;
286d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
287d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
288d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) {
289d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrQuiet;
290d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet;
291d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
292d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
293d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) {
294d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrDieout;
295d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout;
296d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
297d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
298d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) {
299d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrLow;
300d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_low = de_tuning_cfg_data->params.thr_low;
301d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
302d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
303d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) {
304d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.override_flags |= kOverrideDEThrHigh;
305d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        de_data.thr_high = de_tuning_cfg_data->params.thr_high;
306d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
307d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
308d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) {
309d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        switch (de_tuning_cfg_data->params.quality) {
310d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualLow:
311d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityLow;
312d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
313d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualMedium:
314d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityMedium;
315d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
316d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualHigh:
317d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityHigh;
318d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
319d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          case kDeContentQualUnknown:
320d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema          default:
321d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            de_data.quality_level = kContentQualityUnknown;
322d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema            break;
323d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        }
324d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
325d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
326d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    err = hwc_display->SetDetailEnhancerConfig(de_data);
327d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (err) {
328d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("SetDetailEnhancerConfig failed. err = %d", err);
329d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
330d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    de_tuning_cfg_data->cfg_pending = false;
331d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
332d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return err;
333d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
334d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
335d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) {
336d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
337d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
338d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPPendingParams pending_action;
339d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  PPDisplayAPIPayload req_payload;
340d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
341d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  pending_action.action = kGetDetailedEnhancerData;
342d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  pending_action.params = NULL;
343d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
344d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (hwc_display) {
345d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action);
346d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (!err && pending_action.action == kConfigureDetailedEnhancer) {
347d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display);
348d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
349d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
350d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return;
351d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
352d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
353d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) {
354d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  SCOPE_LOCK(locker_);
355d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int err = -1;
356d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  err = SetHWDetailedEnhancerConfig(params, hwc_display);
357d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return err;
358d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
359d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
360d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
361d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
362d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
363d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
364d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema};
365d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
366d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kSocketName = "pps";
367d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
368d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaconst char *const HWCQDCMModeManager::kPackageName = "colormanager";
369d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
370d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
371d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
372d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
373d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!mode_mgr) {
374d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("No memory to create HWCQDCMModeManager.");
375d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return NULL;
376d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {
377d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    mode_mgr->socket_fd_ =
378d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
379d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (mode_mgr->socket_fd_ < 0) {
380d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      // it should not be disastrous and we still can grab wakelock in QDCM mode.
381d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to connect to dpps socket!");
382d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
383d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
384d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // retrieve system GPU idle timeout value for later to recover.
385d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
386d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
387d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
388d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return mode_mgr;
389d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
390d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
391d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaHWCQDCMModeManager::~HWCQDCMModeManager() {
392d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (socket_fd_ >= 0)
393d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    ::close(socket_fd_);
394d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
395d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
396d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCQDCMModeManager::EnableActiveFeatures(bool enable,
397d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
398d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                                             bool *was_running) {
399d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
400d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  ssize_t size = 0;
401d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  char response[kSocketCMDMaxLength] = {
402d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      0,
403d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  };
404d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
405d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (socket_fd_ < 0) {
406d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    DLOGW("No socket connection available!");
407d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    return -EFAULT;
408d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
409d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
410d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (!enable) {  // if client requesting to disable it.
411d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    // query CABL status, if off, no action. keep the status.
412d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
413d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (size < 0) {
414d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      DLOGW("Unable to send data over socket %s", ::strerror(errno));
415d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      ret = -EFAULT;
416d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    } else {
417d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::read(socket_fd_, response, kSocketCMDMaxLength);
418d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
419d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to read data over socket %s", ::strerror(errno));
420d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
421d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
422d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        *was_running = true;
423d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
424d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
425d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
426d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (*was_running) {  // if was running, it's requested to disable it.
427d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
428d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
429d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to send data over socket %s", ::strerror(errno));
430d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
431d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
432d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
433d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  } else {  // if was running, need enable it back.
434d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    if (*was_running) {
435d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
436d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      if (size < 0) {
437d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        DLOGW("Unable to send data over socket %s", ::strerror(errno));
438d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema        ret = -EFAULT;
439d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema      }
440d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    }
441d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
442d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
443d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
444d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
445d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
446d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
447d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  int ret = 0;
448d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
449d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
450d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema                             &cabl_was_running_);
451d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
452d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  // if enter QDCM mode, disable GPU fallback idle timeout.
453d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  if (hwc_display) {
454d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    uint32_t timeout = enable ? 0 : entry_timeout_;
455d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema    hwc_display->SetIdleTimeoutMs(timeout);
456d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  }
457d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
458d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema  return ret;
459d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema}
460d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema
461d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} // namespace sdm
462