Commit 37779cf9 authored by erg@chromium.org's avatar erg@chromium.org

GTK: More profiling of the rendering path.

- Cleanup TabRendererGtk::PaintIcon so select which surface we should paint and
  instead of copy/pasting the same code in each block.
- When calling any version of GtkThemeService::GetCached*, don't first get the
  pixbuf (which can lock) and then check if you have a cairo cached version of
  the pixbuf, discarding the result of locking every time except the first.

BUG=100803
TEST=none


Review URL: http://codereview.chromium.org/8341089

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107817 0039d316-1c4b-4281-b951-d872f2087c98
parent 1c881579
......@@ -566,10 +566,11 @@ void GtkThemeService::GetScrollbarColors(GdkColor* thumb_active_color,
CairoCachedSurface* GtkThemeService::GetSurfaceNamed(
int id,
GtkWidget* widget_on_display) {
return GetSurfaceNamedImpl(id,
&per_display_surfaces_,
GetPixbufNamed(id),
widget_on_display);
return GetSurfaceNamedImpl(
id,
&per_display_surfaces_,
&GtkThemeService::GetPixbufNamed,
widget_on_display);
}
CairoCachedSurface* GtkThemeService::GetRTLEnabledSurfaceNamed(
......@@ -580,10 +581,11 @@ CairoCachedSurface* GtkThemeService::GetRTLEnabledSurfaceNamed(
// location calls this function with a resource ID, and another place calls
// GetSurfaceNamed() with the same ID, they'll correctly get different
// surfaces in RTL mode.
return GetSurfaceNamedImpl(-id,
&per_display_surfaces_,
GetRTLEnabledPixbufNamed(id),
widget_on_display);
return GetSurfaceNamedImpl(
-id,
&per_display_surfaces_,
&GtkThemeService::GetRTLEnabledPixbufNamedWrapper,
widget_on_display);
}
CairoCachedSurface* GtkThemeService::GetUnthemedSurfaceNamed(
......@@ -591,10 +593,19 @@ CairoCachedSurface* GtkThemeService::GetUnthemedSurfaceNamed(
GtkWidget* widget_on_display) {
return GetSurfaceNamedImpl(id,
&per_display_unthemed_surfaces_,
ResourceBundle::GetSharedInstance().GetNativeImageNamed(id),
&GtkThemeService::GetUnthemedNativePixbuf,
widget_on_display);
}
CairoCachedSurface* GtkThemeService::GetCairoIcon(
int id,
GtkWidget* widget_on_display) {
return GetSurfaceNamedImpl(id,
&per_display_icon_surfaces_,
&GtkThemeService::GetPixbufForIconId,
widget_on_display);
}
// static
GdkPixbuf* GtkThemeService::GetFolderIcon(bool native) {
if (native) {
......@@ -704,6 +715,7 @@ void GtkThemeService::FreePlatformCaches() {
ThemeService::FreePlatformCaches();
FreePerDisplaySurfaces(&per_display_surfaces_);
FreePerDisplaySurfaces(&per_display_unthemed_surfaces_);
FreePerDisplaySurfaces(&per_display_icon_surfaces_);
STLDeleteValues(&gtk_images_);
}
......@@ -1124,7 +1136,7 @@ void GtkThemeService::GetSelectedEntryForegroundHSL(
CairoCachedSurface* GtkThemeService::GetSurfaceNamedImpl(
int id,
PerDisplaySurfaceMap* display_surface_map,
GdkPixbuf* pixbuf,
PixbufProvidingMethod provider,
GtkWidget* widget_on_display) {
GdkDisplay* display = gtk_widget_get_display(widget_on_display);
CairoCachedSurfaceMap& surface_map = (*display_surface_map)[display];
......@@ -1135,13 +1147,43 @@ CairoCachedSurface* GtkThemeService::GetSurfaceNamedImpl(
return found->second;
CairoCachedSurface* surface = new CairoCachedSurface;
surface->UsePixbuf(pixbuf);
surface->UsePixbuf((this->*provider)(id));
surface_map[id] = surface;
return surface;
}
// PixbufProvidingMethod that undoes the negative sign on |id|.
GdkPixbuf* GtkThemeService::GetRTLEnabledPixbufNamedWrapper(int id) const {
return GetRTLEnabledPixbufNamed(-id);
}
// PixbufProvidingMethod that just calls ResourceBundle. We want to minimize
// the calls to this method because it aquires an AutoLock and we don't want
// this to happen all the time.
GdkPixbuf* GtkThemeService::GetUnthemedNativePixbuf(int id) const {
return ResourceBundle::GetSharedInstance().GetNativeImageNamed(id);
}
// PixbufProvidingMethod that maps a GtkThemeService::CairoDefaultIcon to a
// GdkPixbuf.
GdkPixbuf* GtkThemeService::GetPixbufForIconId(int id) const {
switch (id) {
case GtkThemeService::NATIVE_FAVICON:
return GtkThemeService::GetDefaultFavicon(true);
case GtkThemeService::CHROME_FAVICON:
return GtkThemeService::GetDefaultFavicon(false);
case GtkThemeService::NATIVE_FOLDER:
return GtkThemeService::GetFolderIcon(true);
case GtkThemeService::CHROME_FOLDER:
return GtkThemeService::GetFolderIcon(false);
default:
NOTREACHED();
return NULL;
}
}
void GtkThemeService::OnDestroyChromeButton(GtkWidget* button) {
std::vector<GtkWidget*>::iterator it =
find(chrome_buttons_.begin(), chrome_buttons_.end(), button);
......
......@@ -35,6 +35,15 @@ typedef struct _GtkWidget GtkWidget;
// Specialization of ThemeService which supplies system colors.
class GtkThemeService : public ThemeService {
public:
// A list of integer keys for a separate PerDisplaySurfaceMap that keeps
// what would otherwise be static icons on the X11 server.
enum CairoDefaultIcon {
NATIVE_FAVICON = 1,
CHROME_FAVICON,
NATIVE_FOLDER,
CHROME_FOLDER
};
// Returns GtkThemeService, casted from our superclass.
static GtkThemeService* GetFrom(Profile* profile);
......@@ -120,6 +129,10 @@ class GtkThemeService : public ThemeService {
CairoCachedSurface* GetUnthemedSurfaceNamed(int id,
GtkWidget* widget_on_display);
// A way to get a cached cairo surface for the equivalent of GetFolderIcon()
// or GetDefaultFavicon(). Uses the ids defined in CairoDefaultIcon.
CairoCachedSurface* GetCairoIcon(int id, GtkWidget* widget_on_display);
// Returns colors that we pass to webkit to match the system theme.
const SkColor& get_focus_ring_color() const { return focus_ring_color_; }
const SkColor& get_thumb_active_color() const { return thumb_active_color_; }
......@@ -156,6 +169,8 @@ class GtkThemeService : public ThemeService {
typedef std::map<int, CairoCachedSurface*> CairoCachedSurfaceMap;
typedef std::map<GdkDisplay*, CairoCachedSurfaceMap> PerDisplaySurfaceMap;
typedef GdkPixbuf*(GtkThemeService::*PixbufProvidingMethod)(int id) const;
// Clears all the GTK color overrides.
virtual void ClearAllThemeData();
......@@ -235,10 +250,21 @@ class GtkThemeService : public ThemeService {
void GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const;
// Implements GetXXXSurfaceNamed(), given the appropriate pixbuf to use.
CairoCachedSurface* GetSurfaceNamedImpl(int id,
PerDisplaySurfaceMap* surface_map,
GdkPixbuf* pixbuf,
GtkWidget* widget_on_display);
CairoCachedSurface* GetSurfaceNamedImpl(
int id,
PerDisplaySurfaceMap* surface_map,
PixbufProvidingMethod provider,
GtkWidget* widget_on_display);
// PixbufProvidingMethods passed to GetSurfaceNamedImpl from GetSurface*
// methods. We don't want to always fetch the pixbuf and pass the pixbuf to
// GetSurfaceNamedImpl which will throw away the result most of the time.
//
// Especially since GetUnthemedNativePixbuf always locks and
// GetRTLEnabledPixbufNamedWrapper locks in debug builds.
GdkPixbuf* GetRTLEnabledPixbufNamedWrapper(int id) const;
GdkPixbuf* GetUnthemedNativePixbuf(int id) const;
GdkPixbuf* GetPixbufForIconId(int id) const;
// Handles signal from GTK that our theme has been changed.
CHROMEGTK_CALLBACK_1(GtkThemeService, void, OnStyleSet, GtkStyle*);
......@@ -306,6 +332,7 @@ class GtkThemeService : public ThemeService {
// Cairo surfaces for each GdkDisplay.
PerDisplaySurfaceMap per_display_surfaces_;
PerDisplaySurfaceMap per_display_unthemed_surfaces_;
PerDisplaySurfaceMap per_display_icon_surfaces_;
PrefChangeRegistrar registrar_;
......
......@@ -846,35 +846,27 @@ void TabRendererGtk::PaintTitle(GtkWidget* widget, cairo_t* cr) {
void TabRendererGtk::PaintIcon(GtkWidget* widget, cairo_t* cr) {
if (loading_animation_.animation_state() != ANIMATION_NONE) {
PaintLoadingAnimation(widget, cr);
} else {
if (should_display_crashed_favicon_) {
theme_service_->GetSurfaceNamed(IDR_SAD_FAVICON, widget)->SetSource(
cr, favicon_bounds_.x(),
favicon_bounds_.y() + favicon_hiding_offset_);
cairo_paint(cr);
} else {
if (!data_.favicon.isNull()) {
if (data_.is_default_favicon && theme_service_->UsingNativeTheme()) {
GdkPixbuf* favicon = GtkThemeService::GetDefaultFavicon(true);
// TODO(erg): Get GtkThemeService to hand us a
// CairoCachedSurface. Then we can simplify all of this.
gdk_cairo_set_source_pixbuf(
cr, favicon, favicon_bounds_.x(),
favicon_bounds_.y() + favicon_hiding_offset_);
cairo_paint(cr);
} else if (data_.cairo_favicon.valid()) {
// TODO(erg): We should research whether we still need to draw app
// icons larger. We don't appear to be getting larger icons.
data_.cairo_favicon.SetSource(
cr,
favicon_bounds_.x(),
favicon_bounds_.y() + favicon_hiding_offset_);
cairo_paint(cr);
}
}
return;
}
CairoCachedSurface* to_display = NULL;
if (should_display_crashed_favicon_) {
to_display = theme_service_->GetSurfaceNamed(IDR_SAD_FAVICON, widget);
} else if (!data_.favicon.isNull()) {
if (data_.is_default_favicon && theme_service_->UsingNativeTheme()) {
to_display = theme_service_->GetCairoIcon(
GtkThemeService::NATIVE_FAVICON, widget);
} else if (data_.cairo_favicon.valid()) {
to_display = &data_.cairo_favicon;
}
}
if (to_display) {
to_display->SetSource(cr,
favicon_bounds_.x(),
favicon_bounds_.y() + favicon_hiding_offset_);
cairo_paint(cr);
}
}
void TabRendererGtk::PaintTabBackground(GtkWidget* widget, cairo_t* cr) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment