1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/ozone/platform/dri/chromeos/display_message_handler.h" 6 7#include "ui/display/types/display_mode.h" 8#include "ui/display/types/display_snapshot.h" 9#include "ui/ozone/common/chromeos/display_util.h" 10#include "ui/ozone/common/gpu/ozone_gpu_message_params.h" 11#include "ui/ozone/common/gpu/ozone_gpu_messages.h" 12#include "ui/ozone/platform/dri/chromeos/native_display_delegate_dri.h" 13 14namespace ui { 15 16namespace { 17 18class FindDisplayById { 19 public: 20 FindDisplayById(int64_t display_id) : display_id_(display_id) {} 21 22 bool operator()(const DisplaySnapshot_Params& display) const { 23 return display.display_id == display_id_; 24 } 25 26 private: 27 int64_t display_id_; 28}; 29 30} // namespace 31 32DisplayMessageHandler::DisplayMessageHandler( 33 scoped_ptr<NativeDisplayDelegateDri> ndd) 34 : sender_(NULL), 35 ndd_(ndd.Pass()) {} 36 37DisplayMessageHandler::~DisplayMessageHandler() {} 38 39void DisplayMessageHandler::OnChannelEstablished(IPC::Sender* sender) { 40 sender_ = sender; 41} 42 43bool DisplayMessageHandler::OnMessageReceived(const IPC::Message& message) { 44 bool handled = true; 45 46 IPC_BEGIN_MESSAGE_MAP(DisplayMessageHandler, message) 47 IPC_MESSAGE_HANDLER(OzoneGpuMsg_ForceDPMSOn, OnForceDPMSOn) 48 IPC_MESSAGE_HANDLER(OzoneGpuMsg_RefreshNativeDisplays, 49 OnRefreshNativeDisplays) 50 IPC_MESSAGE_HANDLER(OzoneGpuMsg_ConfigureNativeDisplay, 51 OnConfigureNativeDisplay) 52 IPC_MESSAGE_HANDLER(OzoneGpuMsg_DisableNativeDisplay, 53 OnDisableNativeDisplay) 54 IPC_MESSAGE_UNHANDLED(handled = false); 55 IPC_END_MESSAGE_MAP() 56 57 return handled; 58} 59 60void DisplayMessageHandler::OnForceDPMSOn() { 61 ndd_->ForceDPMSOn(); 62} 63 64void DisplayMessageHandler::OnRefreshNativeDisplays( 65 const std::vector<DisplaySnapshot_Params>& cached_displays) { 66 std::vector<DisplaySnapshot_Params> displays; 67 std::vector<DisplaySnapshot*> native_displays = ndd_->GetDisplays(); 68 69 // If any of the cached displays are in the list of new displays then apply 70 // their configuration immediately. 71 for (size_t i = 0; i < native_displays.size(); ++i) { 72 std::vector<DisplaySnapshot_Params>::const_iterator it = 73 std::find_if(cached_displays.begin(), 74 cached_displays.end(), 75 FindDisplayById(native_displays[i]->display_id())); 76 77 if (it == cached_displays.end()) 78 continue; 79 80 if (it->has_current_mode) 81 OnConfigureNativeDisplay(it->display_id, it->current_mode, it->origin); 82 else 83 OnDisableNativeDisplay(it->display_id); 84 } 85 86 for (size_t i = 0; i < native_displays.size(); ++i) 87 displays.push_back(GetDisplaySnapshotParams(*native_displays[i])); 88 89 sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(displays)); 90} 91 92void DisplayMessageHandler::OnConfigureNativeDisplay( 93 int64_t id, 94 const DisplayMode_Params& mode_param, 95 const gfx::Point& origin) { 96 DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id); 97 if (!display) { 98 LOG(ERROR) << "There is no display with ID " << id; 99 return; 100 } 101 102 const DisplayMode* mode = NULL; 103 for (size_t i = 0; i < display->modes().size(); ++i) { 104 if (mode_param.size == display->modes()[i]->size() && 105 mode_param.is_interlaced == display->modes()[i]->is_interlaced() && 106 mode_param.refresh_rate == display->modes()[i]->refresh_rate()) { 107 mode = display->modes()[i]; 108 break; 109 } 110 } 111 112 // If the display doesn't have the mode natively, then lookup the mode from 113 // other displays and try using it on the current display (some displays 114 // support panel fitting and they can use different modes even if the mode 115 // isn't explicitly declared). 116 if (!mode) 117 mode = ndd_->FindDisplayMode(mode_param.size, 118 mode_param.is_interlaced, 119 mode_param.refresh_rate); 120 121 if (!mode) { 122 LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString() 123 << " is_interlaced=" << mode_param.is_interlaced 124 << " refresh_rate=" << mode_param.refresh_rate; 125 return; 126 } 127 128 ndd_->Configure(*display, mode, origin); 129} 130 131void DisplayMessageHandler::OnDisableNativeDisplay(int64_t id) { 132 DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id); 133 if (display) 134 ndd_->Configure(*display, NULL, gfx::Point()); 135 else 136 LOG(ERROR) << "There is no display with ID " << id; 137} 138 139} // namespace ui 140