int HWCQDCMModeManager::EnableActiveFeatures(bool enable, const HWCQDCMModeManager::ActiveFeatureCMD &cmds, bool *was_running) { int ret = 0; ssize_t size = 0; char response[kSocketCMDMaxLength] = { 0, }; if (socket_fd_ < 0) { DLOGW("No socket connection available - assuming dpps is not enabled"); return 0; } if (!enable) { // if client requesting to disable it. // query CABL status, if off, no action. keep the status. size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status)); if (size < 0) { DLOGW("Unable to send data over socket %s", ::strerror(errno)); ret = -EFAULT; } else { size = ::read(socket_fd_, response, kSocketCMDMaxLength); if (size < 0) { DLOGW("Unable to read data over socket %s", ::strerror(errno)); ret = -EFAULT; } else if (!strncmp(response, cmds.running, strlen(cmds.running))) { *was_running = true; } } if (*was_running) { // if was running, it's requested to disable it. size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off)); if (size < 0) { DLOGW("Unable to send data over socket %s", ::strerror(errno)); ret = -EFAULT; } } } else { // if was running, need enable it back. if (*was_running) { size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on)); if (size < 0) { DLOGW("Unable to send data over socket %s", ::strerror(errno)); ret = -EFAULT; } } } return ret; }
DisplayError StrategyDefault::GetNextStrategy(StrategyConstraints *constraints, HWLayersInfo *hw_layers_info) { if (hw_layers_info->flags) { DLOGW("All strategies exhausted."); return kErrorUndefined; } // Mark all layers for GPU composition. Find GPU target buffer and store its index for programming // the hardware. LayerStack *layer_stack = hw_layers_info->stack; uint32_t &hw_layer_count = hw_layers_info->count; hw_layer_count = 0; for (uint32_t i = 0; i < layer_stack->layer_count; i++) { LayerComposition &composition = layer_stack->layers[i].composition; if (composition != kCompositionGPUTarget) { composition = kCompositionGPU; } else { hw_layers_info->index[hw_layer_count++] = i; } } // There can be one and only one GPU target buffer. if (hw_layer_count != 1) { return kErrorParameters; } hw_layers_info->flags = 1; return kErrorNone; }
void sprite_init_global_mesh() { if ( g_sprite_mesh.has_been_initalised == TRUE){ DLOGW("Sprite global mesh has already been initialized"); return; } glGenBuffers(1, &g_sprite_mesh.vbo_vertex_array); glBindBuffer(GL_ARRAY_BUFFER, g_sprite_mesh.vbo_vertex_array); GLfloat vertex_array[] = {0, 0, 0, 0 , 0, 1, 0, 0, 1 , 0, 1, -1, 0, 1 , 1, 0, -1, 0 , 0 , 1} ; glBufferData(GL_ARRAY_BUFFER, sizeof (vertex_array), vertex_array, GL_STATIC_DRAW); glGenBuffers(1, &g_sprite_mesh.vbo_element_array); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_sprite_mesh.vbo_element_array); GLushort element_array[] = {0, 3, 2, 0, 2, 1}; glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof (element_array), element_array, GL_STATIC_DRAW); g_sprite_mesh.has_been_initalised = TRUE; }
pollfd HWEvents::InitializePollFd(HWEventData *event_data) { char node_path[kMaxStringLength] = {0}; char data[kMaxStringLength] = {0}; pollfd poll_fd; poll_fd.fd = -1; if (!strncmp(event_data->event_name, "thread_exit", strlen("thread_exit"))) { // Create an eventfd to be used to unblock the poll system call when // a thread is exiting. poll_fd.fd = Sys::eventfd_(0, 0); poll_fd.events |= POLLIN; exit_fd_ = poll_fd.fd; } else { snprintf(node_path, sizeof(node_path), "%s%d/%s", fb_path_, fb_num_, event_data->event_name); poll_fd.fd = Sys::open_(node_path, O_RDONLY); poll_fd.events |= POLLPRI | POLLERR; } if (poll_fd.fd < 0) { DLOGW("open failed for display=%d event=%s, error=%s", fb_num_, event_data->event_name, strerror(errno)); return poll_fd; } // Read once on all fds to clear data on all fds. Sys::pread_(poll_fd.fd, data , kMaxStringLength, 0); return poll_fd; }
void* HWEvents::DisplayEventHandler() { char data[kMaxStringLength] = {0}; prctl(PR_SET_NAME, event_thread_name_.c_str(), 0, 0, 0); setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent); while (!exit_threads_) { int error = Sys::poll_(poll_fds_.data(), UINT32(event_list_->size()), -1); if (error <= 0) { DLOGW("poll failed. error = %s", strerror(errno)); continue; } for (uint32_t event = 0; event < event_list_->size(); event++) { pollfd &poll_fd = poll_fds_[event]; if (!strncmp(event_list_->at(event), "thread_exit", strlen("thread_exit"))) { if ((poll_fd.revents & POLLIN) && (Sys::read_(poll_fd.fd, data, kMaxStringLength) > 0)) { (this->*(event_data_list_[event]).event_parser)(data); } } else { if ((poll_fd.revents & POLLPRI) && (Sys::pread_(poll_fd.fd, data, kMaxStringLength, 0) > 0)) { (this->*(event_data_list_[event]).event_parser)(data); } } } } pthread_exit(0); return NULL; }
HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) { HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator); if (color_mgr) { // Load display API interface library. And retrieve color API function tables. DynLib &color_apis_lib = color_mgr->color_apis_lib_; if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) { if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) { DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES, DISPLAY_API_INTERFACE_LIBRARY_NAME); delete color_mgr; return NULL; } } else { DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); delete color_mgr; return NULL; } DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); // Load diagclient library and invokes its entry point to pass in display APIs. DynLib &diag_client_lib = color_mgr->diag_client_lib_; if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) { if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME, reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) || !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME, reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) { DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME, QDCM_DIAG_CLIENT_LIBRARY_NAME); } else { // invoke Diag Client entry point to initialize. color_mgr->qdcm_diag_init_(color_mgr->color_apis_); DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME, QDCM_DIAG_CLIENT_LIBRARY_NAME); } } else { DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME); // only QDCM Diag client failed to be loaded and system still should function. } } else { DLOGE("Unable to create HWCColorManager"); return NULL; } return color_mgr; }
uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) { uint32_t best_index = 0, index; uint32_t num_modes = 0; hw_intf_->GetNumDisplayAttributes(&num_modes); // Get display attribute for each mode std::vector<HWDisplayAttributes> attrib(num_modes); for (index = 0; index < num_modes; index++) { hw_intf_->GetDisplayAttributes(index, &attrib[index]); } // Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone for (index = 0; index < num_modes; index ++) { if (attrib[index].s3d_config[s3d_mode]) { break; } } if (index < num_modes) { best_index = UINT32(index); for (size_t index = best_index + 1; index < num_modes; index ++) { if (!attrib[index].s3d_config[s3d_mode]) continue; // From the available configs, select the best // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60 if (attrib[index].y_pixels > attrib[best_index].y_pixels) { best_index = UINT32(index); } else if (attrib[index].y_pixels == attrib[best_index].y_pixels) { if (attrib[index].x_pixels > attrib[best_index].x_pixels) { best_index = UINT32(index); } else if (attrib[index].x_pixels == attrib[best_index].x_pixels) { if (attrib[index].vsync_period_ns < attrib[best_index].vsync_period_ns) { best_index = UINT32(index); } } } } } else { DLOGW("%s, could not support S3D mode from EDID info. S3D mode is %d", __FUNCTION__, s3d_mode); } // Used for changing HDMI Resolution - override the best with user set config uint32_t user_config = UINT32(Debug::GetHDMIResolution()); if (user_config) { uint32_t config_index = 0; // For the config, get the corresponding index DisplayError error = hw_intf_->GetConfigIndex(user_config, &config_index); if (error == kErrorNone) return config_index; } return best_index; }
HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() { HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager(); if (!mode_mgr) { DLOGW("No memory to create HWCQDCMModeManager."); return NULL; } else { mode_mgr->socket_fd_ = ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); if (mode_mgr->socket_fd_ < 0) { // it should not be disastrous and we still can grab wakelock in QDCM mode. DLOGW("Unable to connect to dpps socket!"); } // retrieve system GPU idle timeout value for later to recover. mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs()); } return mode_mgr; }
DisplayError ResourceDefault::RegisterDisplay(DisplayType type, const HWDisplayAttributes &display_attributes, const HWPanelInfo &hw_panel_info, const HWMixerAttributes &mixer_attributes, Handle *display_ctx) { DisplayError error = kErrorNone; HWBlockType hw_block_id = kHWBlockMax; switch (type) { case kPrimary: if (!hw_block_ctx_[kHWPrimary].is_in_use) { hw_block_id = kHWPrimary; } break; case kHDMI: if (!hw_block_ctx_[kHWHDMI].is_in_use) { hw_block_id = kHWHDMI; } break; default: DLOGW("RegisterDisplay, invalid type %d", type); return kErrorParameters; } if (hw_block_id == kHWBlockMax) { return kErrorResources; } DisplayResourceContext *display_resource_ctx = new DisplayResourceContext(); if (!display_resource_ctx) { return kErrorMemory; } hw_block_ctx_[hw_block_id].is_in_use = true; display_resource_ctx->display_attributes = display_attributes; display_resource_ctx->hw_block_id = hw_block_id; display_resource_ctx->mixer_attributes = mixer_attributes; *display_ctx = display_resource_ctx; return error; }
DisplayError HWEvents::Deinit() { exit_threads_ = true; Sys::pthread_cancel_(event_thread_); uint64_t exit_value = 1; ssize_t write_size = Sys::write_(exit_fd_, &exit_value, sizeof(uint64_t)); if (write_size != sizeof(uint64_t)) DLOGW("Error triggering exit_fd_ (%d). write size = %d, error = %s", exit_fd_, write_size, strerror(errno)); pthread_join(event_thread_, NULL); for (uint32_t i = 0; i < event_list_->size(); i++) { Sys::close_(poll_fds_[i].fd); poll_fds_[i].fd = -1; } return kErrorNone; }
int HWCDisplayPrimary::Perform(uint32_t operation, ...) { va_list args; va_start(args, operation); int val = 0; LayerRect *rect = NULL; switch (operation) { case SET_METADATA_DYN_REFRESH_RATE: val = va_arg(args, int32_t); SetMetaDataRefreshRateFlag(val); break; case SET_BINDER_DYN_REFRESH_RATE: val = va_arg(args, int32_t); ForceRefreshRate(UINT32(val)); break; case SET_DISPLAY_MODE: val = va_arg(args, int32_t); SetDisplayMode(UINT32(val)); break; case SET_QDCM_SOLID_FILL_INFO: val = va_arg(args, int32_t); SetQDCMSolidFillInfo(true, UINT32(val)); break; case UNSET_QDCM_SOLID_FILL_INFO: val = va_arg(args, int32_t); SetQDCMSolidFillInfo(false, UINT32(val)); break; case SET_QDCM_SOLID_FILL_RECT: rect = va_arg(args, LayerRect*); solid_fill_rect_ = *rect; break; default: DLOGW("Invalid operation %d", operation); va_end(args); return -EINVAL; } va_end(args); return 0; }
int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id, PPDisplayAPIPayload *sink) { int ret = 0; uint32_t id(0); uint32_t size(0); id = UINT32(in.readInt32()); size = UINT32(in.readInt32()); if (size > 0 && size == in.dataAvail()) { const void *data = in.readInplace(size); const uint8_t *temp = reinterpret_cast<const uint8_t *>(data); sink->size = size; sink->payload = const_cast<uint8_t *>(temp); *disp_id = id; } else { DLOGW("Failing size checking, size = %d", size); ret = -EINVAL; } return ret; }
int HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) { int err = -1; DisplayDetailEnhancerData de_data; PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params); if (de_tuning_cfg_data->cfg_pending == true) { if (!de_tuning_cfg_data->cfg_en) { de_data.override_flags = kOverrideDEEnable; de_data.enable = 0; } else { de_data.override_flags = kOverrideDEEnable; de_data.enable = 1; if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) { de_data.override_flags |= kOverrideDESharpen1; de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) { de_data.override_flags |= kOverrideDEClip; de_data.clip = de_tuning_cfg_data->params.clip; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) { de_data.override_flags |= kOverrideDEThrQuiet; de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) { de_data.override_flags |= kOverrideDEThrDieout; de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) { de_data.override_flags |= kOverrideDEThrLow; de_data.thr_low = de_tuning_cfg_data->params.thr_low; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) { de_data.override_flags |= kOverrideDEThrHigh; de_data.thr_high = de_tuning_cfg_data->params.thr_high; } if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) { switch (de_tuning_cfg_data->params.quality) { case kDeContentQualLow: de_data.quality_level = kContentQualityLow; break; case kDeContentQualMedium: de_data.quality_level = kContentQualityMedium; break; case kDeContentQualHigh: de_data.quality_level = kContentQualityHigh; break; case kDeContentQualUnknown: default: de_data.quality_level = kContentQualityUnknown; break; } } } err = hwc_display->SetDetailEnhancerConfig(de_data); if (err) { DLOGW("SetDetailEnhancerConfig failed. err = %d", err); } de_tuning_cfg_data->cfg_pending = false; } return err; }