| OLD | NEW | 
 | (Empty) | 
|    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/display/chromeos/configure_displays_task.h" |  | 
|    6  |  | 
|    7 #include "base/auto_reset.h" |  | 
|    8 #include "base/bind.h" |  | 
|    9 #include "ui/display/chromeos/display_util.h" |  | 
|   10 #include "ui/display/types/display_snapshot.h" |  | 
|   11 #include "ui/display/types/native_display_delegate.h" |  | 
|   12  |  | 
|   13 namespace ui { |  | 
|   14  |  | 
|   15 namespace { |  | 
|   16  |  | 
|   17 // Find the next best mode after |display_mode|. If none can be found return |  | 
|   18 // nullptr. |  | 
|   19 const DisplayMode* FindNextMode(const DisplaySnapshot& display_state, |  | 
|   20                                 const DisplayMode* display_mode) { |  | 
|   21   if (!display_mode) |  | 
|   22     return nullptr; |  | 
|   23  |  | 
|   24   int best_mode_pixels = 0; |  | 
|   25   const DisplayMode* best_mode = nullptr; |  | 
|   26   int current_mode_pixels = display_mode->size().GetArea(); |  | 
|   27   for (const std::unique_ptr<const DisplayMode>& mode : display_state.modes()) { |  | 
|   28     int pixel_count = mode->size().GetArea(); |  | 
|   29     if (pixel_count < current_mode_pixels && pixel_count > best_mode_pixels) { |  | 
|   30       best_mode = mode.get(); |  | 
|   31       best_mode_pixels = pixel_count; |  | 
|   32     } |  | 
|   33   } |  | 
|   34  |  | 
|   35   return best_mode; |  | 
|   36 } |  | 
|   37  |  | 
|   38 }  // namespace |  | 
|   39  |  | 
|   40 DisplayConfigureRequest::DisplayConfigureRequest(DisplaySnapshot* display, |  | 
|   41                                                  const DisplayMode* mode, |  | 
|   42                                                  const gfx::Point& origin) |  | 
|   43     : display(display), mode(mode), origin(origin) { |  | 
|   44 } |  | 
|   45  |  | 
|   46 ConfigureDisplaysTask::ConfigureDisplaysTask( |  | 
|   47     NativeDisplayDelegate* delegate, |  | 
|   48     const std::vector<DisplayConfigureRequest>& requests, |  | 
|   49     const ResponseCallback& callback) |  | 
|   50     : delegate_(delegate), |  | 
|   51       requests_(requests), |  | 
|   52       callback_(callback), |  | 
|   53       is_configuring_(false), |  | 
|   54       num_displays_configured_(0), |  | 
|   55       task_status_(SUCCESS), |  | 
|   56       weak_ptr_factory_(this) { |  | 
|   57   for (size_t i = 0; i < requests_.size(); ++i) |  | 
|   58     pending_request_indexes_.push(i); |  | 
|   59 } |  | 
|   60  |  | 
|   61 ConfigureDisplaysTask::~ConfigureDisplaysTask() { |  | 
|   62 } |  | 
|   63  |  | 
|   64 void ConfigureDisplaysTask::Run() { |  | 
|   65   // Synchronous configurators will recursively call Run(). In that case just |  | 
|   66   // defer their call to the next iteration in the while-loop. This is done to |  | 
|   67   // guard against stack overflows if the display has a large list of broken |  | 
|   68   // modes. |  | 
|   69   if (is_configuring_) |  | 
|   70     return; |  | 
|   71  |  | 
|   72   { |  | 
|   73     base::AutoReset<bool> recursivity_guard(&is_configuring_, true); |  | 
|   74     while (!pending_request_indexes_.empty()) { |  | 
|   75       size_t index = pending_request_indexes_.front(); |  | 
|   76       DisplayConfigureRequest* request = &requests_[index]; |  | 
|   77       pending_request_indexes_.pop(); |  | 
|   78       // Non-native displays do not require configuration through the |  | 
|   79       // NativeDisplayDelegate. |  | 
|   80       if (!IsPhysicalDisplayType(request->display->type())) { |  | 
|   81         OnConfigured(index, true); |  | 
|   82       } else { |  | 
|   83         delegate_->Configure(*request->display, request->mode, request->origin, |  | 
|   84                              base::Bind(&ConfigureDisplaysTask::OnConfigured, |  | 
|   85                                         weak_ptr_factory_.GetWeakPtr(), index)); |  | 
|   86       } |  | 
|   87     } |  | 
|   88   } |  | 
|   89  |  | 
|   90   // Nothing should be modified after the |callback_| is called since the |  | 
|   91   // task may be deleted in the callback. |  | 
|   92   if (num_displays_configured_ == requests_.size()) |  | 
|   93     callback_.Run(task_status_); |  | 
|   94 } |  | 
|   95  |  | 
|   96 void ConfigureDisplaysTask::OnConfigured(size_t index, bool success) { |  | 
|   97   DisplayConfigureRequest* request = &requests_[index]; |  | 
|   98   VLOG(2) << "Configured status=" << success |  | 
|   99           << " display=" << request->display->display_id() |  | 
|  100           << " origin=" << request->origin.ToString() |  | 
|  101           << " mode=" << (request->mode ? request->mode->ToString() : "null"); |  | 
|  102   if (!success) { |  | 
|  103     request->mode = FindNextMode(*request->display, request->mode); |  | 
|  104     if (request->mode) { |  | 
|  105       pending_request_indexes_.push(index); |  | 
|  106       if (task_status_ == SUCCESS) |  | 
|  107         task_status_ = PARTIAL_SUCCESS; |  | 
|  108  |  | 
|  109       Run(); |  | 
|  110       return; |  | 
|  111     } |  | 
|  112   } else { |  | 
|  113     request->display->set_current_mode(request->mode); |  | 
|  114     request->display->set_origin(request->origin); |  | 
|  115   } |  | 
|  116  |  | 
|  117   num_displays_configured_++; |  | 
|  118   if (!success) |  | 
|  119     task_status_ = ERROR; |  | 
|  120  |  | 
|  121   Run(); |  | 
|  122 } |  | 
|  123  |  | 
|  124 }  // namespace ui |  | 
| OLD | NEW |