diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-23 21:36:47 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-23 21:36:47 +0000 |
commit | 4f693b2b63bc60bebe30790a80f8d04a966421af (patch) | |
tree | 959762bfb23ec82ee80a341e466568cf1e84b30a /chrome/browser | |
parent | 840434d046cbaefb5a70875b7e364523c713c79b (diff) | |
download | chromium_src-4f693b2b63bc60bebe30790a80f8d04a966421af.zip chromium_src-4f693b2b63bc60bebe30790a80f8d04a966421af.tar.gz chromium_src-4f693b2b63bc60bebe30790a80f8d04a966421af.tar.bz2 |
Add Linux support for getting the thumbnail and wire into the switcher.
Review URL: http://codereview.chromium.org/144006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19064 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/gtk/tabs/dragged_tab_gtk.cc | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store.h | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_x.cc | 14 | ||||
-rwxr-xr-x | chrome/browser/tab_contents/thumbnail_generator.cc | 73 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_overview_cell.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_overview_controller.cc | 8 |
6 files changed, 79 insertions, 38 deletions
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc index b91cf7b..9a25ca9 100644 --- a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc +++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc @@ -287,11 +287,9 @@ void DraggedTabGtk::PaintScreenshotIntoCanvas(gfx::Canvas* canvas, const gfx::Rect& target_bounds) { gfx::Rect rect(0, 0, contents_->allocation.width, contents_->allocation.height); - SkBitmap* bitmap = backing_store_->PaintRectToBitmap(rect); - if (bitmap) { - canvas->DrawBitmapInt(*bitmap, 0, renderer_->bounds().height()); - delete bitmap; - } + SkBitmap bitmap = backing_store_->PaintRectToBitmap(rect); + if (!bitmap.isNull()) + canvas->DrawBitmapInt(bitmap, 0, renderer_->bounds().height()); } // static diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index 3438bda3..977553f 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -57,14 +57,18 @@ class BackingStore { #elif defined(OS_MACOSX) skia::PlatformCanvas* canvas() { return &canvas_; } #elif defined(OS_LINUX) + Display* display() const { return display_; } + XID root_window() const { return root_window_; }; + // Copy from the server-side backing store to the target window // display: the display of the backing store and target window // damage: the area to copy // target: the X id of the target window void ShowRect(const gfx::Rect& damage, XID target); - // Paints the server-side backing store data to a SkBitmap. - SkBitmap* PaintRectToBitmap(const gfx::Rect& rect); + // Paints the server-side backing store data to a SkBitmap. On failure, the + // return bitmap will be isNull(). + SkBitmap PaintRectToBitmap(const gfx::Rect& rect); #endif // Paints the bitmap from the renderer onto the backing store. diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index 9083dfc..a2397a2 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -313,7 +313,7 @@ void BackingStore::ShowRect(const gfx::Rect& rect, XID target) { rect.x(), rect.y()); } -SkBitmap* BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { +SkBitmap BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { static const int kBytesPerPixel = 4; const int width = rect.width(); @@ -322,18 +322,20 @@ SkBitmap* BackingStore::PaintRectToBitmap(const gfx::Rect& rect) { rect.x(), rect.y(), width, height, AllPlanes, ZPixmap); + + SkBitmap bitmap; + // TODO(jhawkins): Need to convert the image data if the image bits per pixel // is not 32. if (image->bits_per_pixel != 32) { XFree(image); - return NULL; + return bitmap; // Return the empty bitmap to indicate failure. } - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap->allocPixels(); + bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); + bitmap.allocPixels(); unsigned char* bitmap_data = - reinterpret_cast<unsigned char*>(bitmap->getAddr32(0, 0)); + reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)); memcpy(bitmap_data, image->data, width * height * kBytesPerPixel); XFree(image); diff --git a/chrome/browser/tab_contents/thumbnail_generator.cc b/chrome/browser/tab_contents/thumbnail_generator.cc index 681c0c8..e8ed550 100755 --- a/chrome/browser/tab_contents/thumbnail_generator.cc +++ b/chrome/browser/tab_contents/thumbnail_generator.cc @@ -59,6 +59,8 @@ static const int kThumbnailHeight = 204; // painted in this time. static const int kVisibilitySlopMS = 3000; +static const char kThumbnailHistogramName[] = "Thumbnail.ComputeMS"; + struct WidgetThumbnail { SkBitmap thumbnail; @@ -85,9 +87,27 @@ WidgetThumbnail* GetDataForHost(RenderWidgetHost* host) { return GetThumbnailAccessor()->GetProperty(host->property_bag()); } +#if defined(OS_WIN) + +// PlatformDevices/Canvases can't be copied like a regular SkBitmap (at least +// on Windows). So the second parameter is the canvas to draw into. It should +// be sized to the size of the backing store. +void GetBitmapForBackingStore(BackingStore* backing_store, + skia::PlatformCanvas* canvas) { + HDC dc = canvas->beginPlatformPaint(); + BitBlt(dc, 0, 0, + backing_store->size().width(), backing_store->size().height(), + backing_store->hdc(), 0, 0, SRCCOPY); + canvas->endPlatformPaint(); +} + +#endif + // Creates a downsampled thumbnail for the given backing store. The returned // bitmap will be isNull if there was an error creating it. SkBitmap GetThumbnailForBackingStore(BackingStore* backing_store) { + base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now(); + SkBitmap result; // TODO(brettw) write this for other platforms. If you enable this, be sure @@ -97,37 +117,45 @@ SkBitmap GetThumbnailForBackingStore(BackingStore* backing_store) { // Get the bitmap as a Skia object so we can resample it. This is a large // allocation and we can tolerate failure here, so give up if the allocation // fails. - base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now(); - skia::PlatformCanvas temp_canvas; if (!temp_canvas.initialize(backing_store->size().width(), backing_store->size().height(), true)) - return SkBitmap(); - HDC temp_dc = temp_canvas.beginPlatformPaint(); - BitBlt(temp_dc, - 0, 0, backing_store->size().width(), backing_store->size().height(), - backing_store->hdc(), 0, 0, SRCCOPY); - temp_canvas.endPlatformPaint(); + return result; + GetBitmapForBackingStore(backing_store, &temp_canvas); - // Get the bitmap out of the canvas and resample it. + // Get the bitmap out of the canvas and resample it. It would be nice if this + // whole Windows-specific block could be put into a function, but the memory + // management wouldn't work out because the bitmap is a PlatformDevice which + // can't actually be copied. const SkBitmap& bmp = temp_canvas.getTopPlatformDevice().accessBitmap(false); + +#elif defined(OS_LINUX) + SkBitmap bmp = backing_store->PaintRectToBitmap( + gfx::Rect(0, 0, + backing_store->size().width(), backing_store->size().height())); + +#elif defined(OS_MAC) + SkBitmap bmp; + NOTEIMPLEMENTED(); +#endif + result = skia::ImageOperations::DownsampleByTwoUntilSize( bmp, kThumbnailWidth, kThumbnailHeight); - if (bmp.width() == result.width() && bmp.height() == result.height()) { - // This is a bit subtle. SkBitmaps are refcounted, but the magic ones in - // PlatformCanvas can't be ssigned to SkBitmap with proper refcounting. - // If the bitmap doesn't change, then the downsampler will return the input - // bitmap, which will be the reference to the weird PlatformCanvas one - // insetad of a regular one. To get a regular refcounted bitmap, we need to - // copy it. - bmp.copyTo(&result, SkBitmap::kARGB_8888_Config); - } - HISTOGRAM_TIMES("Thumbnail.ComputeOnDestroyMS", - base::TimeTicks::Now() - begin_compute_thumbnail); +#if defined(OS_WIN) + // This is a bit subtle. SkBitmaps are refcounted, but the magic ones in + // PlatformCanvas on Windows can't be ssigned to SkBitmap with proper + // refcounting. If the bitmap doesn't change, then the downsampler will + // return the input bitmap, which will be the reference to the weird + // PlatformCanvas one insetad of a regular one. To get a regular refcounted + // bitmap, we need to copy it. + if (bmp.width() == result.width() && bmp.height() == result.height()) + bmp.copyTo(&result, SkBitmap::kARGB_8888_Config); #endif + HISTOGRAM_TIMES(kThumbnailHistogramName, + base::TimeTicks::Now() - begin_compute_thumbnail); return result; } @@ -165,9 +193,8 @@ SkBitmap ThumbnailGenerator::GetThumbnailForRenderer( RenderWidgetHost* renderer) const { // Return a cached one if we have it and it's still valid. This will only be // valid when there used to be a backing store, but there isn't now. - WidgetThumbnail* wt = GetThumbnailAccessor()->GetProperty( - renderer->property_bag()); - if (wt && !wt->thumbnail.isNull() && + WidgetThumbnail* wt = GetDataForHost(renderer); + if (!wt->thumbnail.isNull() && (no_timeout_ || base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(kVisibilitySlopMS) < wt->last_shown)) diff --git a/chrome/browser/views/tabs/tab_overview_cell.cc b/chrome/browser/views/tabs/tab_overview_cell.cc index c05aae3..b0b5f9f 100644 --- a/chrome/browser/views/tabs/tab_overview_cell.cc +++ b/chrome/browser/views/tabs/tab_overview_cell.cc @@ -6,6 +6,7 @@ #include "app/gfx/favicon_size.h" #include "base/string_util.h" +#include "skia/ext/image_operations.h" #include "views/border.h" #include "views/controls/image_view.h" #include "views/controls/label.h" @@ -64,7 +65,10 @@ TabOverviewCell::TabOverviewCell() { } void TabOverviewCell::SetThumbnail(const SkBitmap& thumbnail) { - thumbnail_view_->SetImage(thumbnail); + // Do mipmapped-based resampling to get closer to the correct size. The + // input bitmap isn't guaranteed to have any specific resolution. + thumbnail_view_->SetImage(skia::ImageOperations::DownsampleByTwoUntilSize( + thumbnail, kThumbnailWidth, kThumbnailHeight)); } void TabOverviewCell::SetTitle(const string16& title) { diff --git a/chrome/browser/views/tabs/tab_overview_controller.cc b/chrome/browser/views/tabs/tab_overview_controller.cc index 86456c1..fb7dfa4 100644 --- a/chrome/browser/views/tabs/tab_overview_controller.cc +++ b/chrome/browser/views/tabs/tab_overview_controller.cc @@ -5,8 +5,10 @@ #include "chrome/browser/views/tabs/tab_overview_controller.h" #include "chrome/browser/browser.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/thumbnail_generator.h" #include "chrome/browser/views/tabs/tab_overview_cell.h" #include "chrome/browser/views/tabs/tab_overview_container.h" #include "chrome/browser/views/tabs/tab_overview_grid.h" @@ -107,10 +109,14 @@ void TabOverviewController::Show() { void TabOverviewController::ConfigureCell(TabOverviewCell* cell, TabContents* contents) { - // TODO: need to set thumbnail here. if (contents) { cell->SetTitle(contents->GetTitle()); cell->SetFavIcon(contents->GetFavIcon()); + + ThumbnailGenerator* generator = g_browser_process->GetThumbnailGenerator(); + cell->SetThumbnail( + generator->GetThumbnailForRenderer(contents->render_view_host())); + cell->SchedulePaint(); } else { // Need to figure out under what circumstances this is null and deal. |