OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/navigation_entry_screenshot_manager.h" | 5 #include "content/browser/frame_host/navigation_entry_screenshot_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/threading/worker_pool.h" | 8 #include "base/threading/worker_pool.h" |
9 #include "content/browser/frame_host/navigation_controller_impl.h" | 9 #include "content/browser/frame_host/navigation_controller_impl.h" |
10 #include "content/browser/frame_host/navigation_entry_impl.h" | 10 #include "content/browser/frame_host/navigation_entry_impl.h" |
11 #include "content/browser/renderer_host/render_view_host_impl.h" | 11 #include "content/browser/renderer_host/render_view_host_impl.h" |
12 #include "content/public/browser/overscroll_configuration.h" | 12 #include "content/public/browser/overscroll_configuration.h" |
13 #include "content/public/browser/render_widget_host.h" | 13 #include "content/public/browser/render_widget_host.h" |
14 #include "content/public/browser/render_widget_host_view.h" | 14 #include "content/public/browser/render_widget_host_view.h" |
15 #include "content/public/common/content_switches.h" | 15 #include "content/public/common/content_switches.h" |
16 #include "third_party/skia/include/core/SkCanvas.h" | |
17 #include "third_party/skia/include/core/SkPaint.h" | |
18 #include "third_party/skia/include/effects/SkLumaColorFilter.h" | |
19 #include "ui/gfx/codec/png_codec.h" | 16 #include "ui/gfx/codec/png_codec.h" |
20 | 17 |
21 namespace { | 18 namespace { |
22 | 19 |
23 // Minimum delay between taking screenshots. | 20 // Minimum delay between taking screenshots. |
24 const int kMinScreenshotIntervalMS = 1000; | 21 const int kMinScreenshotIntervalMS = 1000; |
25 | 22 |
26 } | 23 } |
27 | 24 |
28 namespace content { | 25 namespace content { |
29 | 26 |
30 // Converts SkBitmap to grayscale and encodes to PNG data in a worker thread. | 27 // Encodes the A8 SkBitmap to grayscale PNG in a worker thread. |
31 class ScreenshotData : public base::RefCountedThreadSafe<ScreenshotData> { | 28 class ScreenshotData : public base::RefCountedThreadSafe<ScreenshotData> { |
32 public: | 29 public: |
33 ScreenshotData() { | 30 ScreenshotData() { |
34 } | 31 } |
35 | 32 |
36 void EncodeScreenshot(const SkBitmap& bitmap, base::Closure callback) { | 33 void EncodeScreenshot(const SkBitmap& bitmap, base::Closure callback) { |
37 if (!base::WorkerPool::PostTaskAndReply(FROM_HERE, | 34 if (!base::WorkerPool::PostTaskAndReply(FROM_HERE, |
38 base::Bind(&ScreenshotData::EncodeOnWorker, | 35 base::Bind(&ScreenshotData::EncodeOnWorker, |
39 this, | 36 this, |
40 bitmap), | 37 bitmap), |
41 callback, | 38 callback, |
42 true)) { | 39 true)) { |
43 callback.Run(); | 40 callback.Run(); |
44 } | 41 } |
45 } | 42 } |
46 | 43 |
47 scoped_refptr<base::RefCountedBytes> data() const { return data_; } | 44 scoped_refptr<base::RefCountedBytes> data() const { return data_; } |
48 | 45 |
49 private: | 46 private: |
50 friend class base::RefCountedThreadSafe<ScreenshotData>; | 47 friend class base::RefCountedThreadSafe<ScreenshotData>; |
51 virtual ~ScreenshotData() { | 48 virtual ~ScreenshotData() { |
52 } | 49 } |
53 | 50 |
54 void EncodeOnWorker(const SkBitmap& bitmap) { | 51 void EncodeOnWorker(const SkBitmap& bitmap) { |
| 52 DCHECK_EQ(bitmap.colorType(), kAlpha_8_SkColorType); |
| 53 // Encode the A8 bitmap to grayscale PNG treating alpha as color intensity. |
55 std::vector<unsigned char> data; | 54 std::vector<unsigned char> data; |
56 // Paint |bitmap| to a kAlpha_8_SkColorType SkBitmap | 55 if (gfx::PNGCodec::EncodeA8SkBitmap(bitmap, &data)) |
57 SkBitmap a8Bitmap; | |
58 a8Bitmap.allocPixels(SkImageInfo::MakeA8(bitmap.width(), bitmap.height())); | |
59 SkCanvas canvas(a8Bitmap); | |
60 SkPaint paint; | |
61 SkColorFilter* filter = SkLumaColorFilter::Create(); | |
62 paint.setColorFilter(filter); | |
63 filter->unref(); | |
64 canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); | |
65 // Encode the a8Bitmap to grayscale PNG treating alpha as color intensity | |
66 if (gfx::PNGCodec::EncodeA8SkBitmap(a8Bitmap, &data)) | |
67 data_ = new base::RefCountedBytes(data); | 56 data_ = new base::RefCountedBytes(data); |
68 } | 57 } |
69 | 58 |
70 scoped_refptr<base::RefCountedBytes> data_; | 59 scoped_refptr<base::RefCountedBytes> data_; |
71 | 60 |
72 DISALLOW_COPY_AND_ASSIGN(ScreenshotData); | 61 DISALLOW_COPY_AND_ASSIGN(ScreenshotData); |
73 }; | 62 }; |
74 | 63 |
75 NavigationEntryScreenshotManager::NavigationEntryScreenshotManager( | 64 NavigationEntryScreenshotManager::NavigationEntryScreenshotManager( |
76 NavigationControllerImpl* owner) | 65 NavigationControllerImpl* owner) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 owner_->GetEntryAtIndex(i))); | 112 owner_->GetEntryAtIndex(i))); |
124 } | 113 } |
125 DCHECK_EQ(GetScreenshotCount(), 0); | 114 DCHECK_EQ(GetScreenshotCount(), 0); |
126 } | 115 } |
127 | 116 |
128 void NavigationEntryScreenshotManager::TakeScreenshotImpl( | 117 void NavigationEntryScreenshotManager::TakeScreenshotImpl( |
129 RenderViewHost* host, | 118 RenderViewHost* host, |
130 NavigationEntryImpl* entry) { | 119 NavigationEntryImpl* entry) { |
131 DCHECK(host && host->GetView()); | 120 DCHECK(host && host->GetView()); |
132 DCHECK(entry); | 121 DCHECK(entry); |
133 SkColorType preferred_format = host->PreferredReadbackFormat(); | |
134 host->CopyFromBackingStore( | 122 host->CopyFromBackingStore( |
135 gfx::Rect(), | 123 gfx::Rect(), |
136 host->GetView()->GetViewBounds().size(), | 124 host->GetView()->GetViewBounds().size(), |
137 base::Bind(&NavigationEntryScreenshotManager::OnScreenshotTaken, | 125 base::Bind(&NavigationEntryScreenshotManager::OnScreenshotTaken, |
138 screenshot_factory_.GetWeakPtr(), | 126 screenshot_factory_.GetWeakPtr(), |
139 entry->GetUniqueID()), | 127 entry->GetUniqueID()), |
140 preferred_format); | 128 kAlpha_8_SkColorType); |
141 } | 129 } |
142 | 130 |
143 void NavigationEntryScreenshotManager::SetMinScreenshotIntervalMS( | 131 void NavigationEntryScreenshotManager::SetMinScreenshotIntervalMS( |
144 int interval_ms) { | 132 int interval_ms) { |
145 DCHECK_GE(interval_ms, 0); | 133 DCHECK_GE(interval_ms, 0); |
146 min_screenshot_interval_ms_ = interval_ms; | 134 min_screenshot_interval_ms_ = interval_ms; |
147 } | 135 } |
148 | 136 |
149 void NavigationEntryScreenshotManager::OnScreenshotTaken(int unique_id, | 137 void NavigationEntryScreenshotManager::OnScreenshotTaken(int unique_id, |
150 bool success, | 138 bool success, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 owner_->GetEntryAtIndex(forward)); | 271 owner_->GetEntryAtIndex(forward)); |
284 if (ClearScreenshot(entry)) | 272 if (ClearScreenshot(entry)) |
285 --screenshot_count; | 273 --screenshot_count; |
286 ++forward; | 274 ++forward; |
287 } | 275 } |
288 CHECK_GE(screenshot_count, 0); | 276 CHECK_GE(screenshot_count, 0); |
289 CHECK_LE(screenshot_count, kMaxScreenshots); | 277 CHECK_LE(screenshot_count, kMaxScreenshots); |
290 } | 278 } |
291 | 279 |
292 } // namespace content | 280 } // namespace content |
OLD | NEW |