diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-09 23:07:10 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-09 23:07:10 +0000 |
commit | 40bad03889d4fc90799fdfe39a3fd503cdfb492e (patch) | |
tree | 97aaad871aabb0c5d6610a2f6b5cd090cab2ecf2 /chrome/browser/gtk/cairo_cached_surface.cc | |
parent | cdbb8e420ace50fb0fe7bf57f82f000b45ed09cd (diff) | |
download | chromium_src-40bad03889d4fc90799fdfe39a3fd503cdfb492e.zip chromium_src-40bad03889d4fc90799fdfe39a3fd503cdfb492e.tar.gz chromium_src-40bad03889d4fc90799fdfe39a3fd503cdfb492e.tar.bz2 |
Upload GdkPixbufs into cairo surfaces so they (hopefully) live on the X server and have better performance. In the presence of XRender, let cairo do things smarter.
This is a big win performance wise. BrowserWindowGtk::OnCustomFrameExpose, a heavy user of images sped up from an average runtime of 20.5ms to 0.7ms.
TEST=Run through valgrind, don't leak memory.
TEST=Run both before and after using xtrace. Notice fewer XCreatePixmap requests and more XRender-CreatePicture requests.
BUG=http://crbug.com/10499
Review URL: http://codereview.chromium.org/197046
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25814 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/cairo_cached_surface.cc')
-rw-r--r-- | chrome/browser/gtk/cairo_cached_surface.cc | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/chrome/browser/gtk/cairo_cached_surface.cc b/chrome/browser/gtk/cairo_cached_surface.cc new file mode 100644 index 0000000..90e0ae4 --- /dev/null +++ b/chrome/browser/gtk/cairo_cached_surface.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/cairo_cached_surface.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +CairoCachedSurface::CairoCachedSurface() : pixbuf_(NULL), surface_(NULL) { +} + +CairoCachedSurface::~CairoCachedSurface() { + if (surface_) + cairo_surface_destroy(surface_); + + if (pixbuf_) + g_object_unref(pixbuf_); +} + +int CairoCachedSurface::Width() const { + return pixbuf_ ? gdk_pixbuf_get_width(pixbuf_) : -1; +} + +int CairoCachedSurface::Height() const { + return pixbuf_ ? gdk_pixbuf_get_height(pixbuf_) : -1; +} + +void CairoCachedSurface::UsePixbuf(GdkPixbuf* pixbuf) { + if (surface_) { + cairo_surface_destroy(surface_); + surface_ = NULL; + } + + if (pixbuf) + g_object_ref(pixbuf); + + if (pixbuf_) + g_object_unref(pixbuf_); + + pixbuf_ = pixbuf; +} + +void CairoCachedSurface::SetSource(cairo_t* cr, int x, int y) { + DCHECK(pixbuf_); + DCHECK(cr); + + if (!surface_) { + // First time here since last UsePixbuf call. Generate the surface. + cairo_surface_t* target = cairo_get_target(cr); + surface_ = cairo_surface_create_similar( + target, + CAIRO_CONTENT_COLOR_ALPHA, + gdk_pixbuf_get_width(pixbuf_), + gdk_pixbuf_get_height(pixbuf_)); + + DCHECK(surface_); + DCHECK(cairo_surface_get_type(surface_) == CAIRO_SURFACE_TYPE_XLIB || + cairo_surface_get_type(surface_) == CAIRO_SURFACE_TYPE_XCB); + + cairo_t* copy_cr = cairo_create(surface_); + gdk_cairo_set_source_pixbuf(copy_cr, pixbuf_, 0, 0); + cairo_paint(copy_cr); + cairo_destroy(copy_cr); + } + + cairo_set_source_surface(cr, surface_, x, y); +} |