Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: athena/content/content_proxy.cc

Issue 863033002: Delete athena/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « athena/content/content_proxy.h ('k') | athena/content/media_utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "athena/content/content_proxy.h"
6
7 #include "base/bind.h"
8 #include "base/threading/worker_pool.h"
9 #include "content/public/browser/render_view_host.h"
10 #include "content/public/browser/render_widget_host_view.h"
11 #include "content/public/browser/web_contents.h"
12 #include "ui/aura/window.h"
13 #include "ui/gfx/codec/png_codec.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/image/image.h"
16 #include "ui/gfx/image/image_png_rep.h"
17 #include "ui/views/controls/webview/webview.h"
18 #include "ui/views/widget/widget.h"
19
20 namespace athena {
21
22 // Encodes an A8 SkBitmap to grayscale PNG in a worker thread.
23 class ProxyImageData : public base::RefCountedThreadSafe<ProxyImageData> {
24 public:
25 ProxyImageData() {
26 }
27
28 void EncodeImage(const SkBitmap& bitmap, base::Closure callback) {
29 if (!base::WorkerPool::PostTaskAndReply(FROM_HERE,
30 base::Bind(&ProxyImageData::EncodeOnWorker,
31 this,
32 bitmap),
33 callback,
34 true)) {
35 // When coming here, the resulting image will be empty.
36 DCHECK(false) << "Cannot start bitmap encode task.";
37 callback.Run();
38 }
39 }
40
41 scoped_refptr<base::RefCountedBytes> data() const { return data_; }
42
43 private:
44 friend class base::RefCountedThreadSafe<ProxyImageData>;
45 ~ProxyImageData() {}
46
47 void EncodeOnWorker(const SkBitmap& bitmap) {
48 DCHECK_EQ(bitmap.colorType(), kAlpha_8_SkColorType);
49 // Encode the A8 bitmap to grayscale PNG treating alpha as color intensity.
50 std::vector<unsigned char> data;
51 if (gfx::PNGCodec::EncodeA8SkBitmap(bitmap, &data))
52 data_ = new base::RefCountedBytes(data);
53 }
54
55 scoped_refptr<base::RefCountedBytes> data_;
56
57 DISALLOW_COPY_AND_ASSIGN(ProxyImageData);
58 };
59
60 ContentProxy::ContentProxy(views::WebView* web_view)
61 : web_view_(web_view),
62 content_visible_(true),
63 content_loaded_(true),
64 content_creation_called_(false),
65 proxy_content_to_image_factory_(this) {
66 // Note: The content will be hidden once the image got created.
67 CreateProxyContent();
68 }
69
70 ContentProxy::~ContentProxy() {
71 // If we still have a connection to the original web contents, we make it
72 // visible again.
73 ShowOriginalContent();
74 }
75
76 void ContentProxy::ContentWillUnload() {
77 content_loaded_ = false;
78 }
79
80 gfx::ImageSkia ContentProxy::GetContentImage() {
81 // While we compress to PNG, we use the original read back.
82 if (!png_data_.get())
83 return raw_image_;
84
85 // Otherwise we convert the PNG.
86 std::vector<gfx::ImagePNGRep> image_reps;
87 image_reps.push_back(gfx::ImagePNGRep(png_data_, 1.0f));
88 return *(gfx::Image(image_reps).ToImageSkia());
89 }
90
91 void ContentProxy::EvictContent() {
92 raw_image_ = gfx::ImageSkia();
93 png_data_->Release();
94 }
95
96 void ContentProxy::OnPreContentDestroyed() {
97 // Since we are breaking now the connection to the old content, we make the
98 // content visible again before we continue.
99 // Note: Since the owning window is invisible, it does not matter that we
100 // make the web content visible if the window gets destroyed shortly after.
101 ShowOriginalContent();
102
103 web_view_ = nullptr;
104 }
105
106 void ContentProxy::ShowOriginalContent() {
107 if (web_view_ && !content_visible_) {
108 // Show the original |web_view_| again.
109 web_view_->SetFastResize(false);
110 // If the content is loaded, we ask it to relayout itself since the
111 // dimensions might have changed. If not, we will reload new content and no
112 // layout is required for the old content.
113 if (content_loaded_)
114 web_view_->Layout();
115 web_view_->GetWebContents()->GetNativeView()->Show();
116 web_view_->SetVisible(true);
117 content_visible_ = true;
118 }
119 }
120
121 void ContentProxy::HideOriginalContent() {
122 if (web_view_ && content_visible_) {
123 // Hide the |web_view_|.
124 // TODO(skuhne): We might consider removing the view from the window while
125 // it's hidden - it should work the same way as show/hide and does not have
126 // any window re-ordering effect. Furthermore we want possibly to suppress
127 // any resizing of content (not only fast resize) here to avoid jank on
128 // rotation.
129 web_view_->GetWebContents()->GetNativeView()->Hide();
130 web_view_->SetVisible(false);
131 // Don't allow the content to get resized with window size changes.
132 web_view_->SetFastResize(true);
133 content_visible_ = false;
134 }
135 }
136
137 void ContentProxy::CreateProxyContent() {
138 DCHECK(!content_creation_called_);
139 content_creation_called_ = true;
140 // Unit tests might not have a |web_view_|.
141 if (!web_view_)
142 return;
143
144 content::RenderViewHost* host =
145 web_view_->GetWebContents()->GetRenderViewHost();
146 DCHECK(host);
147 // A never fully initialized content can come here with no view.
148 if (!host->GetView())
149 return;
150 gfx::Size source = host->GetView()->GetViewBounds().size();
151 gfx::Size target = gfx::Size(source.width() / 2, source.height() / 2);
152 host->CopyFromBackingStore(
153 gfx::Rect(),
154 target,
155 base::Bind(&ContentProxy::OnContentImageRead,
156 proxy_content_to_image_factory_.GetWeakPtr()),
157 kAlpha_8_SkColorType);
158 }
159
160 void ContentProxy::OnContentImageRead(const SkBitmap& bitmap,
161 content::ReadbackResponse response) {
162 // Now we can hide the content. Note that after hiding we are freeing memory
163 // and if something goes wrong we will end up with an empty page.
164 HideOriginalContent();
165
166 if (response != content::READBACK_SUCCESS || bitmap.empty() ||
167 bitmap.isNull())
168 return;
169
170 // While we are encoding the image, we keep the current image as reference
171 // to have something for the overview mode to grab. Once we have the encoded
172 // PNG, we will get rid of this.
173 raw_image_ = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
174
175 scoped_refptr<ProxyImageData> png_image = new ProxyImageData();
176 png_image->EncodeImage(
177 bitmap,
178 base::Bind(&ContentProxy::OnContentImageEncodeComplete,
179 proxy_content_to_image_factory_.GetWeakPtr(),
180 png_image));
181 }
182
183 void ContentProxy::OnContentImageEncodeComplete(
184 scoped_refptr<ProxyImageData> image) {
185 png_data_ = image->data();
186
187 // From now on we decode the image as needed to save memory.
188 raw_image_ = gfx::ImageSkia();
189 }
190
191 } // namespace athena
OLDNEW
« no previous file with comments | « athena/content/content_proxy.h ('k') | athena/content/media_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698