| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/tab_contents/thumbnail_generator.h" | 5 #include "chrome/browser/tab_contents/thumbnail_generator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/scoped_ptr.h" |
| 11 #include "base/time.h" | 12 #include "base/time.h" |
| 12 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 13 #include "chrome/browser/renderer_host/backing_store.h" | 14 #include "chrome/browser/renderer_host/backing_store.h" |
| 15 #include "chrome/browser/renderer_host/render_process_host.h" |
| 14 #include "chrome/browser/renderer_host/render_view_host.h" | 16 #include "chrome/browser/renderer_host/render_view_host.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | 17 #include "chrome/browser/tab_contents/tab_contents.h" |
| 16 #include "chrome/common/notification_service.h" | 18 #include "chrome/common/notification_service.h" |
| 17 #include "chrome/common/property_bag.h" | 19 #include "chrome/common/property_bag.h" |
| 18 #include "gfx/rect.h" | 20 #include "gfx/rect.h" |
| 19 #include "gfx/skbitmap_operations.h" | 21 #include "gfx/skbitmap_operations.h" |
| 20 #include "skia/ext/platform_canvas.h" | 22 #include "skia/ext/platform_canvas.h" |
| 21 #include "third_party/skia/include/core/SkBitmap.h" | 23 #include "third_party/skia/include/core/SkBitmap.h" |
| 22 | 24 |
| 25 #if defined(OS_WIN) |
| 26 #include "app/win_util.h" |
| 27 #endif |
| 28 |
| 23 // Overview | 29 // Overview |
| 24 // -------- | 30 // -------- |
| 25 // This class provides current thumbnails for tabs. The simplest operation is | 31 // This class provides current thumbnails for tabs. The simplest operation is |
| 26 // when a request for a thumbnail comes in, to grab the backing store and make | 32 // when a request for a thumbnail comes in, to grab the backing store and make |
| 27 // a smaller version of that. | 33 // a smaller version of that. |
| 28 // | 34 // |
| 29 // A complication happens because we don't always have nice backing stores for | 35 // A complication happens because we don't always have nice backing stores for |
| 30 // all tabs (there is a cache of several tabs we'll keep backing stores for). | 36 // all tabs (there is a cache of several tabs we'll keep backing stores for). |
| 31 // To get thumbnails for tabs with expired backing stores, we listen for | 37 // To get thumbnails for tabs with expired backing stores, we listen for |
| 32 // backing stores that are being thrown out, and generate thumbnails before | 38 // backing stores that are being thrown out, and generate thumbnails before |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 return; | 191 return; |
| 186 } | 192 } |
| 187 // Now, if the backing store didn't exist, we will still try and | 193 // Now, if the backing store didn't exist, we will still try and |
| 188 // render asynchronously. | 194 // render asynchronously. |
| 189 } | 195 } |
| 190 | 196 |
| 191 // We are going to render the thumbnail asynchronously now, so keep | 197 // We are going to render the thumbnail asynchronously now, so keep |
| 192 // this callback for later lookup when the rendering is done. | 198 // this callback for later lookup when the rendering is done. |
| 193 static int sequence_num = 0; | 199 static int sequence_num = 0; |
| 194 sequence_num++; | 200 sequence_num++; |
| 195 TransportDIB* thumbnail_dib = TransportDIB::Create( | 201 scoped_ptr<TransportDIB> thumbnail_dib(TransportDIB::Create( |
| 196 desired_size.width() * desired_size.height() * 4, sequence_num); | 202 desired_size.width() * desired_size.height() * 4, sequence_num)); |
| 203 |
| 204 #if defined(OS_WIN) |
| 205 // Duplicate the handle to the DIB here because the renderer process does not |
| 206 // have permission. The duplicated handle is owned by the renderer process, |
| 207 // which is responsible for closing it. |
| 208 TransportDIB::Handle renderer_dib_handle = win_util::GetSectionForProcess( |
| 209 thumbnail_dib->handle(), |
| 210 renderer->process()->GetHandle(), |
| 211 false); |
| 212 if (!renderer_dib_handle) { |
| 213 LOG(WARNING) << "Could not duplicate dib handle for renderer"; |
| 214 delete callback; |
| 215 return; |
| 216 } |
| 217 #else |
| 218 TransportDIB::Handle renderer_dib_handle = thumbnail_dib->handle(); |
| 219 #endif |
| 197 | 220 |
| 198 linked_ptr<AsyncRequestInfo> request_info(new AsyncRequestInfo); | 221 linked_ptr<AsyncRequestInfo> request_info(new AsyncRequestInfo); |
| 199 request_info->callback.reset(callback); | 222 request_info->callback.reset(callback); |
| 200 request_info->thumbnail_dib.reset(thumbnail_dib); | 223 request_info->thumbnail_dib.reset(thumbnail_dib.release()); |
| 201 request_info->renderer = renderer; | 224 request_info->renderer = renderer; |
| 202 ThumbnailCallbackMap::value_type new_value(sequence_num, request_info); | 225 ThumbnailCallbackMap::value_type new_value(sequence_num, request_info); |
| 203 std::pair<ThumbnailCallbackMap::iterator, bool> result = | 226 std::pair<ThumbnailCallbackMap::iterator, bool> result = |
| 204 callback_map_.insert(new_value); | 227 callback_map_.insert(new_value); |
| 205 if (!result.second) { | 228 if (!result.second) { |
| 206 NOTREACHED() << "Callback already registered?"; | 229 NOTREACHED() << "Callback already registered?"; |
| 207 return; | 230 return; |
| 208 } | 231 } |
| 209 | 232 |
| 210 renderer->PaintAtSize( | 233 renderer->PaintAtSize( |
| 211 thumbnail_dib->handle(), sequence_num, page_size, desired_size); | 234 renderer_dib_handle, sequence_num, page_size, desired_size); |
| 212 } | 235 } |
| 213 | 236 |
| 214 SkBitmap ThumbnailGenerator::GetThumbnailForRenderer( | 237 SkBitmap ThumbnailGenerator::GetThumbnailForRenderer( |
| 215 RenderWidgetHost* renderer) const { | 238 RenderWidgetHost* renderer) const { |
| 216 WidgetThumbnail* wt = GetDataForHost(renderer); | 239 WidgetThumbnail* wt = GetDataForHost(renderer); |
| 217 | 240 |
| 218 BackingStore* backing_store = renderer->GetBackingStore(false); | 241 BackingStore* backing_store = renderer->GetBackingStore(false); |
| 219 if (!backing_store) { | 242 if (!backing_store) { |
| 220 // When we have no backing store, there's no choice in what to use. We | 243 // When we have no backing store, there's no choice in what to use. We |
| 221 // have to return either the existing thumbnail or the empty one if there | 244 // have to return either the existing thumbnail or the empty one if there |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 315 |
| 293 void ThumbnailGenerator::WidgetDidReceivePaintAtSizeAck( | 316 void ThumbnailGenerator::WidgetDidReceivePaintAtSizeAck( |
| 294 RenderWidgetHost* widget, | 317 RenderWidgetHost* widget, |
| 295 int sequence_num, | 318 int sequence_num, |
| 296 const gfx::Size& size) { | 319 const gfx::Size& size) { |
| 297 // Lookup the callback, run it, and erase it. | 320 // Lookup the callback, run it, and erase it. |
| 298 ThumbnailCallbackMap::iterator item = callback_map_.find(sequence_num); | 321 ThumbnailCallbackMap::iterator item = callback_map_.find(sequence_num); |
| 299 if (item != callback_map_.end()) { | 322 if (item != callback_map_.end()) { |
| 300 TransportDIB* dib = item->second->thumbnail_dib.get(); | 323 TransportDIB* dib = item->second->thumbnail_dib.get(); |
| 301 DCHECK(dib); | 324 DCHECK(dib); |
| 302 if (!dib) { | 325 if (!dib || !dib->Map()) { |
| 303 return; | 326 return; |
| 304 } | 327 } |
| 305 | 328 |
| 306 // Create an SkBitmap from the DIB. | 329 // Create an SkBitmap from the DIB. |
| 307 SkBitmap non_owned_bitmap; | 330 SkBitmap non_owned_bitmap; |
| 308 SkBitmap result; | 331 SkBitmap result; |
| 309 | 332 |
| 310 // Fill out the non_owned_bitmap with the right config. Note that | 333 // Fill out the non_owned_bitmap with the right config. Note that |
| 311 // this code assumes that the transport dib is a 32-bit ARGB | 334 // this code assumes that the transport dib is a 32-bit ARGB |
| 312 // image. | 335 // image. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 &ThumbnailGenerator::ShownDelayHandler); | 468 &ThumbnailGenerator::ShownDelayHandler); |
| 446 } | 469 } |
| 447 } | 470 } |
| 448 | 471 |
| 449 void ThumbnailGenerator::EraseHostFromShownList(RenderWidgetHost* widget) { | 472 void ThumbnailGenerator::EraseHostFromShownList(RenderWidgetHost* widget) { |
| 450 std::vector<RenderWidgetHost*>::iterator found = | 473 std::vector<RenderWidgetHost*>::iterator found = |
| 451 std::find(shown_hosts_.begin(), shown_hosts_.end(), widget); | 474 std::find(shown_hosts_.begin(), shown_hosts_.end(), widget); |
| 452 if (found != shown_hosts_.end()) | 475 if (found != shown_hosts_.end()) |
| 453 shown_hosts_.erase(found); | 476 shown_hosts_.erase(found); |
| 454 } | 477 } |
| OLD | NEW |