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

Side by Side Diff: chrome/browser/gtk/tabs/dragged_tab_gtk.cc

Issue 155321: Improve performance of dragged tab renderering.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/tabs/dragged_tab_gtk.h ('k') | chrome/browser/renderer_host/backing_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/gtk/tabs/dragged_tab_gtk.h" 5 #include "chrome/browser/gtk/tabs/dragged_tab_gtk.h"
6 6
7 #include <gdk/gdk.h> 7 #include <gdk/gdk.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "app/gfx/canvas_paint.h" 11 #include "app/gfx/canvas_paint.h"
12 #include "base/gfx/gtk_util.h" 12 #include "base/gfx/gtk_util.h"
13 #include "chrome/browser/tab_contents/tab_contents.h" 13 #include "chrome/browser/tab_contents/tab_contents.h"
14 #include "chrome/browser/tabs/tab_strip_model.h" 14 #include "chrome/browser/tabs/tab_strip_model.h"
15 #include "chrome/browser/gtk/tabs/tab_renderer_gtk.h" 15 #include "chrome/browser/gtk/tabs/tab_renderer_gtk.h"
16 #include "chrome/common/gtk_util.h" 16 #include "chrome/common/gtk_util.h"
17 #include "chrome/common/x11_util.h"
17 #include "third_party/skia/include/core/SkShader.h" 18 #include "third_party/skia/include/core/SkShader.h"
18 19
19 namespace { 20 namespace {
20 21
21 // The size of the dragged window frame. 22 // The size of the dragged window frame.
22 const int kDragFrameBorderSize = 2; 23 const int kDragFrameBorderSize = 1;
23 const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize; 24 const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize;
24 25
25 // Used to scale the dragged window sizes. 26 // Used to scale the dragged window sizes.
26 const float kScalingFactor = 0.5; 27 const float kScalingFactor = 0.5;
27 28
28 const int kAnimateToBoundsDurationMs = 150; 29 const int kAnimateToBoundsDurationMs = 150;
29 30
30 const gdouble kTransparentAlpha = (200.0f / 255.0f); 31 const gdouble kTransparentAlpha = (200.0f / 255.0f);
31 const gdouble kOpaqueAlpha = 1.0f; 32 const gdouble kOpaqueAlpha = 1.0f;
32 const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162); 33 const double kDraggedTabBorderColor[] = { 103.0 / 0xff,
34 129.0 / 0xff,
35 162.0 / 0xff };
33 36
34 } // namespace 37 } // namespace
35 38
36 //////////////////////////////////////////////////////////////////////////////// 39 ////////////////////////////////////////////////////////////////////////////////
37 // DraggedTabGtk, public: 40 // DraggedTabGtk, public:
38 41
39 DraggedTabGtk::DraggedTabGtk(TabContents* datasource, 42 DraggedTabGtk::DraggedTabGtk(TabContents* datasource,
40 const gfx::Point& mouse_tab_offset, 43 const gfx::Point& mouse_tab_offset,
41 const gfx::Size& contents_size) 44 const gfx::Size& contents_size)
42 : backing_store_(NULL), 45 : backing_store_(NULL),
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 // If rgba is not available, use rgb instead. 192 // If rgba is not available, use rgb instead.
190 if (!colormap) 193 if (!colormap)
191 colormap = gdk_screen_get_rgb_colormap(screen); 194 colormap = gdk_screen_get_rgb_colormap(screen);
192 195
193 gtk_widget_set_colormap(container_, colormap); 196 gtk_widget_set_colormap(container_, colormap);
194 } 197 }
195 198
196 void DraggedTabGtk::SetContainerTransparency() { 199 void DraggedTabGtk::SetContainerTransparency() {
197 cairo_t* cairo_context = gdk_cairo_create(container_->window); 200 cairo_t* cairo_context = gdk_cairo_create(container_->window);
198 if (!cairo_context) 201 if (!cairo_context)
199 return; 202 return;
200 203
201 // Make the background of the dragged tab window fully transparent. All of 204 // Make the background of the dragged tab window fully transparent. All of
202 // the content of the window (child widgets) will be completely opaque. 205 // the content of the window (child widgets) will be completely opaque.
203 gfx::Size size = bounds().size(); 206 gfx::Size size = bounds().size();
204 cairo_scale(cairo_context, static_cast<double>(size.width()), 207 cairo_scale(cairo_context, static_cast<double>(size.width()),
205 static_cast<double>(size.height())); 208 static_cast<double>(size.height()));
206 cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f); 209 cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f);
207 cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE); 210 cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
208 cairo_paint(cairo_context); 211 cairo_paint(cairo_context);
209 cairo_destroy(cairo_context); 212 cairo_destroy(cairo_context);
210 } 213 }
211 214
212 void DraggedTabGtk::SetContainerShapeMask(const SkBitmap& dragged_contents) { 215 void DraggedTabGtk::SetContainerShapeMask(GdkPixbuf* pixbuf) {
213 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&dragged_contents);
214
215 // Create a 1bpp bitmap the size of |container_|. 216 // Create a 1bpp bitmap the size of |container_|.
216 gfx::Size size = bounds().size(); 217 gfx::Size size = bounds().size();
217 GdkPixmap* pixmap = gdk_pixmap_new(NULL, size.width(), size.height(), 1); 218 GdkPixmap* pixmap = gdk_pixmap_new(NULL, size.width(), size.height(), 1);
218 cairo_t* cairo_context = gdk_cairo_create(GDK_DRAWABLE(pixmap)); 219 cairo_t* cairo_context = gdk_cairo_create(GDK_DRAWABLE(pixmap));
219 220
220 // Set the transparency. 221 // Set the transparency.
221 cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f); 222 cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f);
222 223
223 // Blit the rendered bitmap into a pixmap. Any pixel set in the pixmap will 224 // Blit the rendered bitmap into a pixmap. Any pixel set in the pixmap will
224 // be opaque in the container window. 225 // be opaque in the container window.
225 cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE); 226 cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
227 if (!attached_)
228 cairo_scale(cairo_context, kScalingFactor, kScalingFactor);
226 gdk_cairo_set_source_pixbuf(cairo_context, pixbuf, 0, 0); 229 gdk_cairo_set_source_pixbuf(cairo_context, pixbuf, 0, 0);
227 cairo_paint(cairo_context); 230 cairo_paint(cairo_context);
231
232 if (!attached_) {
233 // Make the render area depiction opaque (leaving enough room for the
234 // border).
235 cairo_identity_matrix(cairo_context);
236 cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 1.0f);
237 int tab_height = kScalingFactor * gdk_pixbuf_get_height(pixbuf) -
238 kDragFrameBorderSize;
239 cairo_rectangle(cairo_context,
240 0, tab_height,
241 size.width(), size.height() - tab_height);
242 cairo_fill(cairo_context);
243 }
244
228 cairo_destroy(cairo_context); 245 cairo_destroy(cairo_context);
229 246
230 // Set the shape mask. 247 // Set the shape mask.
231 gdk_window_shape_combine_mask(container_->window, pixmap, 0, 0); 248 gdk_window_shape_combine_mask(container_->window, pixmap, 0, 0);
232 g_object_unref(pixbuf);
233 g_object_unref(pixmap); 249 g_object_unref(pixmap);
234 } 250 }
235 251
236 SkBitmap DraggedTabGtk::PaintAttachedTab() { 252 GdkPixbuf* DraggedTabGtk::PaintTab() {
237 return renderer_->PaintBitmap(); 253 SkBitmap bitmap = renderer_->PaintBitmap();
238 } 254 return gfx::GdkPixbufFromSkBitmap(&bitmap);
239
240 SkBitmap DraggedTabGtk::PaintDetachedView() {
241 gfx::Size ps = GetPreferredSize();
242 gfx::Canvas scale_canvas(ps.width(), ps.height(), false);
243 SkBitmap& bitmap_device = const_cast<SkBitmap&>(
244 scale_canvas.getTopPlatformDevice().accessBitmap(true));
245 bitmap_device.eraseARGB(0, 0, 0, 0);
246
247 scale_canvas.FillRectInt(kDraggedTabBorderColor, 0,
248 attached_tab_size_.height() - kDragFrameBorderSize,
249 ps.width(), ps.height() - attached_tab_size_.height());
250 int image_x = kDragFrameBorderSize;
251 int image_y = attached_tab_size_.height();
252 int image_w = ps.width() - kTwiceDragFrameBorderSize;
253 int image_h =
254 ps.height() - kTwiceDragFrameBorderSize - attached_tab_size_.height();
255 scale_canvas.FillRectInt(SK_ColorBLACK, image_x, image_y, image_w, image_h);
256 PaintScreenshotIntoCanvas(&scale_canvas,
257 gfx::Rect(image_x, image_y, image_w, image_h));
258 renderer_->Paint(&scale_canvas);
259
260 SkIRect subset;
261 subset.set(0, 0, ps.width(), ps.height());
262 SkBitmap mipmap = scale_canvas.ExtractBitmap();
263 mipmap.buildMipMap(true);
264
265 SkShader* bitmap_shader =
266 SkShader::CreateBitmapShader(mipmap, SkShader::kClamp_TileMode,
267 SkShader::kClamp_TileMode);
268
269 SkMatrix shader_scale;
270 shader_scale.setScale(kScalingFactor, kScalingFactor);
271 bitmap_shader->setLocalMatrix(shader_scale);
272
273 SkPaint paint;
274 paint.setShader(bitmap_shader);
275 paint.setAntiAlias(true);
276 bitmap_shader->unref();
277
278 SkRect rc;
279 rc.fLeft = 0;
280 rc.fTop = 0;
281 rc.fRight = SkIntToScalar(ps.width());
282 rc.fBottom = SkIntToScalar(ps.height());
283 gfx::Canvas canvas(ps.width(), ps.height(), false);
284 canvas.drawRect(rc, paint);
285
286 return canvas.ExtractBitmap();
287 }
288
289 void DraggedTabGtk::PaintScreenshotIntoCanvas(gfx::Canvas* canvas,
290 const gfx::Rect& target_bounds) {
291 // A drag could be initiated before the backing store is created.
292 if (!backing_store_)
293 return;
294
295 gfx::Rect rect(0, 0, target_bounds.width(), target_bounds.height());
296 SkBitmap bitmap = backing_store_->PaintRectToBitmap(rect);
297 if (!bitmap.isNull())
298 canvas->DrawBitmapInt(bitmap, target_bounds.x(), target_bounds.y());
299 } 255 }
300 256
301 // static 257 // static
302 gboolean DraggedTabGtk::OnExposeEvent(GtkWidget* widget, 258 gboolean DraggedTabGtk::OnExposeEvent(GtkWidget* widget,
303 GdkEventExpose* event, 259 GdkEventExpose* event,
304 DraggedTabGtk* dragged_tab) { 260 DraggedTabGtk* dragged_tab) {
305 SkBitmap bmp; 261 GdkPixbuf* pixbuf = dragged_tab->PaintTab();
306 if (dragged_tab->attached_) {
307 bmp = dragged_tab->PaintAttachedTab();
308 } else {
309 bmp = dragged_tab->PaintDetachedView();
310 }
311
312 if (gtk_util::IsScreenComposited()) { 262 if (gtk_util::IsScreenComposited()) {
313 dragged_tab->SetContainerTransparency(); 263 dragged_tab->SetContainerTransparency();
314 } else { 264 } else {
315 dragged_tab->SetContainerShapeMask(bmp); 265 dragged_tab->SetContainerShapeMask(pixbuf);
316 } 266 }
317 267
318 gfx::CanvasPaint canvas(event, false); 268 // Only used when not attached.
319 canvas.DrawBitmapInt(bmp, 0, 0); 269 int tab_height = kScalingFactor * gdk_pixbuf_get_height(pixbuf);
270 int tab_width = kScalingFactor * gdk_pixbuf_get_width(pixbuf);
271
272 // Draw the render area.
273 if (dragged_tab->backing_store_ && !dragged_tab->attached_) {
274 // This leaves room for the border.
275 dragged_tab->backing_store_->PaintToRect(
276 gfx::Rect(kDragFrameBorderSize, tab_height,
277 widget->allocation.width - kTwiceDragFrameBorderSize,
278 widget->allocation.height - tab_height -
279 kDragFrameBorderSize),
280 GDK_DRAWABLE(widget->window));
281 }
282
283 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
284 // Draw the border.
285 if (!dragged_tab->attached_) {
286 cairo_set_line_width(cr, kDragFrameBorderSize);
287 cairo_set_source_rgb(cr, kDraggedTabBorderColor[0],
288 kDraggedTabBorderColor[1],
289 kDraggedTabBorderColor[2]);
290 // |offset| is the distance from the edge of the image to the middle of
291 // the border line.
292 double offset = kDragFrameBorderSize / 2.0 - 0.5;
293 double left_x = offset;
294 double top_y = tab_height - kDragFrameBorderSize + offset;
295 double right_x = widget->allocation.width - offset;
296 double bottom_y = widget->allocation.height - offset;
297 double middle_x = tab_width + offset;
298
299 // We don't use cairo_rectangle() because we don't want to draw the border
300 // under the tab itself.
301 cairo_move_to(cr, left_x, top_y);
302 cairo_line_to(cr, left_x, bottom_y);
303 cairo_line_to(cr, right_x, bottom_y);
304 cairo_line_to(cr, right_x, top_y);
305 cairo_line_to(cr, middle_x, top_y);
306 cairo_stroke(cr);
307 }
308
309 // Draw the tab.
310 if (!dragged_tab->attached_)
311 cairo_scale(cr, kScalingFactor, kScalingFactor);
312 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
313 cairo_paint(cr);
314
315 cairo_destroy(cr);
316
317 g_object_unref(pixbuf);
320 318
321 // We've already drawn the tab, so don't propagate the expose-event signal. 319 // We've already drawn the tab, so don't propagate the expose-event signal.
322 return TRUE; 320 return TRUE;
323 } 321 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/tabs/dragged_tab_gtk.h ('k') | chrome/browser/renderer_host/backing_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698