summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 21:36:47 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 21:36:47 +0000
commit4f693b2b63bc60bebe30790a80f8d04a966421af (patch)
tree959762bfb23ec82ee80a341e466568cf1e84b30a /chrome/browser
parent840434d046cbaefb5a70875b7e364523c713c79b (diff)
downloadchromium_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.cc8
-rw-r--r--chrome/browser/renderer_host/backing_store.h8
-rw-r--r--chrome/browser/renderer_host/backing_store_x.cc14
-rwxr-xr-xchrome/browser/tab_contents/thumbnail_generator.cc73
-rw-r--r--chrome/browser/views/tabs/tab_overview_cell.cc6
-rw-r--r--chrome/browser/views/tabs/tab_overview_controller.cc8
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.