summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 20:04:28 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-09 20:04:28 +0000
commit449478308895f2f09eacfb4971b9917627aa3152 (patch)
tree8e5986eb759388f6eafb16dcbb532b850516e5c4
parent7670df01a5a53fc1c39a0e0008813985d80ebae7 (diff)
downloadchromium_src-449478308895f2f09eacfb4971b9917627aa3152.zip
chromium_src-449478308895f2f09eacfb4971b9917627aa3152.tar.gz
chromium_src-449478308895f2f09eacfb4971b9917627aa3152.tar.bz2
Modified ThumbnailStore to cache/store JPEGs instead
of SkBitmaps. Add command line flag "--thumbnail-store" to enable using the ThumbnailStore facility instead of the current ThumbnailDatabase. Original review: http://codereview.chromium.org/118409 Patch by Meelap Shah git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17971 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/dom_ui/dom_ui_thumbnail_source.cc22
-rw-r--r--chrome/browser/profile.cc13
-rw-r--r--chrome/browser/profile.h7
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc14
-rw-r--r--chrome/browser/thumbnail_store.cc134
-rw-r--r--chrome/browser/thumbnail_store.h18
-rw-r--r--chrome/browser/thumbnail_store_unittest.cc75
-rw-r--r--chrome/chrome.gyp3
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--chrome/test/testing_profile.h5
-rw-r--r--chrome/test/unit/unittests.vcproj4
13 files changed, 185 insertions, 124 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index b20ce97..c6bbe8b 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2805,6 +2805,14 @@
>
</File>
<File
+ RelativePath=".\thumbnail_store.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\thumbnail_store.h"
+ >
+ </File>
+ <File
RelativePath=".\toolbar_model.cc"
>
</File>
diff --git a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc
index df9c675..9f3d175 100644
--- a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc
+++ b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc
@@ -5,10 +5,15 @@
#include "chrome/browser/dom_ui/dom_ui_thumbnail_source.h"
#include "app/resource_bundle.h"
+#include "base/command_line.h"
+#include "base/gfx/jpeg_codec.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/thumbnail_store.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
#include "grit/theme_resources.h"
+#include "third_party/skia/include/core/SkBitmap.h"
DOMUIThumbnailSource::DOMUIThumbnailSource(Profile* profile)
: DataSource(chrome::kChromeUIThumbnailPath, MessageLoop::current()),
@@ -17,6 +22,23 @@ DOMUIThumbnailSource::DOMUIThumbnailSource(Profile* profile)
void DOMUIThumbnailSource::StartDataRequest(const std::string& path,
int request_id) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kThumbnailStore)) {
+ ThumbnailStore* store = profile_->GetThumbnailStore();
+ RefCountedBytes* data = NULL;
+
+ if (!store->GetPageThumbnail(GURL(path), &data)) {
+ if (!default_thumbnail_.get()) {
+ default_thumbnail_ = new RefCountedBytes;
+ ResourceBundle::GetSharedInstance().LoadImageResourceBytes(
+ IDR_DEFAULT_THUMBNAIL, &default_thumbnail_->data);
+ }
+ SendResponse(request_id, default_thumbnail_);
+ return;
+ }
+ SendResponse(request_id, data);
+ return;
+ }
+
HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
if (hs) {
HistoryService::Handle handle = hs->GetPageThumbnail(
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index f493a42..b7bd98d 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/spellchecker.h"
#include "chrome/browser/ssl/ssl_host_state.h"
+#include "chrome/browser/thumbnail_store.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/visitedlink_master.h"
#include "chrome/browser/webdata/web_data_service.h"
@@ -343,6 +344,10 @@ class OffTheRecordProfileImpl : public Profile,
return profile_->GetSpellChecker();
}
+ virtual ThumbnailStore* GetThumbnailStore() {
+ return NULL;
+ }
+
virtual void MarkAsCleanShutdown() {
}
@@ -926,6 +931,14 @@ TabRestoreService* ProfileImpl::GetTabRestoreService() {
return tab_restore_service_.get();
}
+ThumbnailStore* ProfileImpl::GetThumbnailStore() {
+ if (!thumbnail_store_.get()) {
+ thumbnail_store_ = new ThumbnailStore;
+ thumbnail_store_->Init(GetPath().AppendASCII("thumbnailstore\\"));
+ }
+ return thumbnail_store_.get();
+}
+
void ProfileImpl::ResetTabRestoreService() {
tab_restore_service_ = NULL;
}
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index d5e800f..0c6179e 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -24,6 +24,7 @@ namespace net {
class ForceTLSState;
}
class BookmarkModel;
+class BrowserThemeProvider;
class ChromeURLRequestContext;
class DownloadManager;
class Extension;
@@ -40,7 +41,7 @@ class SQLitePersistentCookieStore;
class TabRestoreService;
class TemplateURLFetcher;
class TemplateURLModel;
-class BrowserThemeProvider;
+class ThumbnailStore;
class URLRequestContext;
class UserScriptMaster;
class VisitedLinkMaster;
@@ -190,6 +191,8 @@ class Profile {
// Returns or creates the ThemeProvider associated with this profile
virtual ThemeProvider* GetThemeProvider() = 0;
+ virtual ThumbnailStore* GetThumbnailStore() = 0;
+
// Returns the request context information associated with this profile. Call
// this only on the UI thread, since it can send notifications that should
// happen on the UI thread.
@@ -327,6 +330,7 @@ class ProfileImpl : public Profile,
virtual void SetTheme(Extension* extension);
virtual void ClearTheme();
virtual ThemeProvider* GetThemeProvider();
+ virtual ThumbnailStore* GetThumbnailStore();
virtual bool HasCreatedDownloadManager() const;
virtual URLRequestContext* GetRequestContext();
virtual URLRequestContext* GetRequestContextForMedia();
@@ -391,6 +395,7 @@ class ProfileImpl : public Profile,
scoped_ptr<SSLHostState> ssl_host_state_;
scoped_ptr<net::ForceTLSState> force_tls_state_;
scoped_ptr<PrefService> prefs_;
+ scoped_refptr<ThumbnailStore> thumbnail_store_;
scoped_ptr<TemplateURLFetcher> template_url_fetcher_;
scoped_ptr<TemplateURLModel> template_url_model_;
scoped_ptr<BookmarkModel> bookmark_bar_model_;
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index db21d93..a39f7eb 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -37,6 +37,7 @@
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/thumbnail_store.h"
#include "chrome/browser/search_engines/template_url_fetcher.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/common/chrome_switches.h"
@@ -1633,10 +1634,15 @@ void TabContents::UpdateThumbnail(const GURL& url,
const SkBitmap& bitmap,
const ThumbnailScore& score) {
// Tell History about this thumbnail
- HistoryService* hs;
- if (!profile()->IsOffTheRecord() &&
- (hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS))) {
- hs->SetPageThumbnail(url, bitmap, score);
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kThumbnailStore)) {
+ profile()->GetThumbnailStore()->
+ SetPageThumbnail(url, bitmap, score, !profile()->IsOffTheRecord());
+ } else {
+ HistoryService* hs;
+ if (!profile()->IsOffTheRecord() &&
+ (hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS))) {
+ hs->SetPageThumbnail(url, bitmap, score);
+ }
}
}
diff --git a/chrome/browser/thumbnail_store.cc b/chrome/browser/thumbnail_store.cc
index 1745431..c599c20 100644
--- a/chrome/browser/thumbnail_store.cc
+++ b/chrome/browser/thumbnail_store.cc
@@ -23,62 +23,57 @@ ThumbnailStore::~ThumbnailStore() {
}
void ThumbnailStore::Init(const FilePath& file_path) {
- file_path_ = file_path.DirName();
+ file_path_ = file_path;
g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &ThumbnailStore::GetAllThumbnailsFromDisk,
file_path_, MessageLoop::current()));
}
-void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) {
- if (cache) {
- cache_.reset(cache);
- cache_initialized_ = true;
- }
-}
-
void ThumbnailStore::GetAllThumbnailsFromDisk(FilePath filepath,
MessageLoop* cb_loop) {
- // Create the specified directory if it does not exist.
- if (!file_util::DirectoryExists(filepath) &&
- !file_util::CreateDirectory(filepath))
- return;
-
- // Walk the directory and read the thumbnail data from disk.
- FilePath path;
- GURL url;
- SkBitmap image;
- ThumbnailScore score;
ThumbnailStore::Cache* cache = new ThumbnailStore::Cache;
- file_util::FileEnumerator fenum(filepath, false,
- file_util::FileEnumerator::FILES);
- while (!(path = fenum.Next()).empty()) {
- if (GetPageThumbnailFromDisk(path, &url, &image, &score))
- (*cache)[url] = std::make_pair(image, score);
+ // Create the specified directory if it does not exist.
+ if (!file_util::DirectoryExists(filepath)) {
+ file_util::CreateDirectory(filepath);
+ } else {
+ // Walk the directory and read the thumbnail data from disk.
+ FilePath path;
+ GURL url;
+ RefCountedBytes* data = new RefCountedBytes;
+ ThumbnailScore score;
+ file_util::FileEnumerator fenum(filepath, false,
+ file_util::FileEnumerator::FILES);
+
+ while (!(path = fenum.Next()).empty()) {
+ if (GetPageThumbnailFromDisk(path, &url, data, &score))
+ (*cache)[url] = std::make_pair(data, score);
+ }
}
-
cb_loop->PostTask(FROM_HERE,
NewRunnableMethod(this, &ThumbnailStore::OnDiskDataAvailable, cache));
}
bool ThumbnailStore::GetPageThumbnailFromDisk(const FilePath& file,
- GURL* url, SkBitmap* thumbnail,
+ GURL* url,
+ RefCountedBytes* data,
ThumbnailScore* score) const {
int64 file_size;
if (!file_util::GetFileSize(file, &file_size))
return false;
// Read the file into a buffer.
- std::vector<char> data;
- data.resize(static_cast<unsigned int>(file_size));
- if (file_util::ReadFile(file, &data[0], static_cast<int>(file_size)) == -1)
+ std::vector<char> file_data;
+ file_data.resize(static_cast<unsigned int>(file_size));
+ if (file_util::ReadFile(file, &file_data[0],
+ static_cast<int>(file_size)) == -1)
return false;
// Unpack the url, ThumbnailScore and JPEG size from the buffer.
std::string url_string;
unsigned int jpeg_len;
void* iter = NULL;
- Pickle packed(&data[0], static_cast<int>(file_size));
+ Pickle packed(&file_data[0], static_cast<int>(file_size));
if (!packed.ReadString(&iter, &url_string) ||
!UnpackScore(score, packed, iter) ||
@@ -90,25 +85,28 @@ bool ThumbnailStore::GetPageThumbnailFromDisk(const FilePath& file,
url->Swap(&temp_url);
// Unpack the JPEG data from the buffer.
- if (thumbnail) {
- const char* jpeg_data = NULL;
- int out_len;
-
- if (!packed.ReadData(&iter, &jpeg_data, &out_len) ||
- out_len != jpeg_len)
- return false;
-
- // Convert the jpeg_data to an SkBitmap.
- SkBitmap* thumbnail_ = JPEGCodec::Decode(
- reinterpret_cast<const unsigned char*>(jpeg_data), jpeg_len);
- *thumbnail = *thumbnail_;
- delete thumbnail_;
- }
+ const char* jpeg_data = NULL;
+ int out_len;
+
+ if (!packed.ReadData(&iter, &jpeg_data, &out_len) ||
+ out_len != jpeg_len)
+ return false;
+
+ // Copy jpeg data to the out parameter.
+ data->data.resize(jpeg_len);
+ memcpy(&data->data[0], jpeg_data, jpeg_len);
return true;
}
+void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) {
+ if (cache) {
+ cache_.reset(cache);
+ cache_initialized_ = true;
+ }
+}
+
bool ThumbnailStore::SetPageThumbnail(const GURL& url,
- SkBitmap& thumbnail,
+ const SkBitmap& thumbnail,
const ThumbnailScore& score,
bool write_to_disk) {
if (!cache_initialized_)
@@ -119,8 +117,26 @@ bool ThumbnailStore::SetPageThumbnail(const GURL& url,
!ShouldReplaceThumbnailWith((*cache_)[url].second, score))
return true;
+ base::TimeTicks encode_start = base::TimeTicks::Now();
+
+ // Encode the SkBitmap to jpeg and add to cache.
+ RefCountedBytes* jpeg_data = new RefCountedBytes;
+ SkAutoLockPixels thumbnail_lock(thumbnail);
+ bool encoded = JPEGCodec::Encode(
+ reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)),
+ JPEGCodec::FORMAT_BGRA, thumbnail.width(),
+ thumbnail.height(),
+ static_cast<int>(thumbnail.rowBytes()), 90,
+ &jpeg_data->data);
+
+ base::TimeDelta delta = base::TimeTicks::Now() - encode_start;
+ HISTOGRAM_TIMES("Thumbnail.Encode", delta);
+
+ if (!encoded)
+ return false;
+
// Update the cache_ with the new thumbnail.
- (*cache_)[url] = std::make_pair(thumbnail, score);
+ (*cache_)[url] = std::make_pair(jpeg_data, score);
// Write the new thumbnail data to disk in the background on file_thread.
if (write_to_disk) {
@@ -134,27 +150,14 @@ bool ThumbnailStore::WriteThumbnailToDisk(const GURL& url) const {
// Thumbnail data will be stored in a file named url.host().
FilePath file = file_path_.AppendASCII(url.host());
Pickle packed;
- SkBitmap thumbnail = (*cache_)[url].first;
+ scoped_refptr<RefCountedBytes> data((*cache_)[url].first);
ThumbnailScore score = (*cache_)[url].second;
- // Convert the SkBitmap to a JPEG.
- std::vector<unsigned char> jpeg_data;
- SkAutoLockPixels thumbnail_lock(thumbnail);
- bool encoded = JPEGCodec::Encode(
- reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)),
- JPEGCodec::FORMAT_BGRA, thumbnail.width(),
- thumbnail.height(),
- static_cast<int>(thumbnail.rowBytes()), 90,
- &jpeg_data);
-
- if (!encoded)
- return false;
-
// Pack the url, ThumbnailScore, and the JPEG data.
packed.WriteString(url.spec());
PackScore(score, &packed);
- packed.WriteUInt32(jpeg_data.size());
- packed.WriteData(reinterpret_cast<char*>(&jpeg_data[0]), jpeg_data.size());
+ packed.WriteUInt32(data->data.size());
+ packed.WriteData(reinterpret_cast<char*>(&data->data[0]), data->data.size());
// Write the packed data to a file.
file_util::Delete(file, false);
@@ -163,14 +166,13 @@ bool ThumbnailStore::WriteThumbnailToDisk(const GURL& url) const {
packed.size()) != -1;
}
-bool ThumbnailStore::GetPageThumbnail(const GURL& url, SkBitmap* thumbnail,
- ThumbnailScore* score) {
+bool ThumbnailStore::GetPageThumbnail(const GURL& url, RefCountedBytes** data) {
if (!cache_initialized_ ||
cache_->find(url) == cache_->end())
return false;
- *thumbnail = (*cache_)[url].first;
- *score = (*cache_)[url].second;
+ *data = (*cache_)[url].first;
+ (*data)->AddRef();
return true;
}
@@ -178,7 +180,7 @@ void ThumbnailStore::PackScore(const ThumbnailScore& score,
Pickle* packed) const {
// Pack the contents of the given ThumbnailScore into the given Pickle.
packed->WriteData(reinterpret_cast<const char*>(&score.boring_score),
- sizeof(score.boring_score));
+ sizeof(score.boring_score));
packed->WriteBool(score.at_top);
packed->WriteBool(score.good_clipping);
packed->WriteInt64(score.time_at_snapshot.ToInternalValue());
diff --git a/chrome/browser/thumbnail_store.h b/chrome/browser/thumbnail_store.h
index 46b6ae0..486f99c 100644
--- a/chrome/browser/thumbnail_store.h
+++ b/chrome/browser/thumbnail_store.h
@@ -11,6 +11,7 @@
#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
+#include "chrome/common/ref_counted_util.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
class GURL;
@@ -37,23 +38,22 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore> {
// If write_to_disk is true, the thumbnail data is written to disk on the
// file_thread.
bool SetPageThumbnail(const GURL& url,
- SkBitmap& thumbnail,
+ const SkBitmap& thumbnail,
const ThumbnailScore& score,
bool write_to_disk);
- // Retrieves the thumbnail and score for the given url.
+ // Sets *data to point to the thumbnail for the given url.
// Returns false if there is not data for the given url or some other
// error occurred.
- bool GetPageThumbnail(const GURL& url,
- SkBitmap* thumbnail,
- ThumbnailScore* score);
+ bool GetPageThumbnail(const GURL& url, RefCountedBytes** data);
private:
FRIEND_TEST(ThumbnailStoreTest, RetrieveFromCache);
FRIEND_TEST(ThumbnailStoreTest, RetrieveFromDisk);
// Data structure used to store thumbnail data in memory.
- typedef std::map<GURL, std::pair<SkBitmap, ThumbnailScore> > Cache;
+ typedef std::map<GURL, std::pair<scoped_refptr<RefCountedBytes>,
+ ThumbnailScore> > Cache;
// The location of the thumbnail store.
FilePath file_path_;
@@ -67,7 +67,7 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore> {
// out parameters GURL, SkBitmap, and ThumbnailScore.
bool GetPageThumbnailFromDisk(const FilePath& file,
GURL* url,
- SkBitmap* thumbnail,
+ RefCountedBytes* data,
ThumbnailScore* score) const;
// Once thumbnail data from the disk is available from the file_thread,
@@ -86,11 +86,11 @@ class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore> {
bool UnpackScore(ThumbnailScore* score, const Pickle& packed,
void*& iter) const;
- DISALLOW_COPY_AND_ASSIGN(ThumbnailStore);
-
// The Cache maintained by the object.
scoped_ptr<ThumbnailStore::Cache> cache_;
bool cache_initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThumbnailStore);
};
#endif // CHROME_BROWSER_THUMBNAIL_STORE_H_
diff --git a/chrome/browser/thumbnail_store_unittest.cc b/chrome/browser/thumbnail_store_unittest.cc
index 53ec322..eb00993 100644
--- a/chrome/browser/thumbnail_store_unittest.cc
+++ b/chrome/browser/thumbnail_store_unittest.cc
@@ -12,7 +12,9 @@
#include "base/file_util.h"
#include "base/gfx/jpeg_codec.h"
#include "base/path_service.h"
+#include "base/ref_counted.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/ref_counted_util.h"
#include "chrome/common/thumbnail_score.h"
#include "chrome/tools/profiles/thumbnail-inl.h"
#include "googleurl/src/gurl.h"
@@ -46,7 +48,8 @@ class ThumbnailStoreTest : public testing::Test {
// The directory where ThumbnailStore will store data.
FilePath file_path_;
- SkBitmap read_image_, image_enc_dec_, image_;
+ SkBitmap image_;
+ scoped_refptr<RefCountedBytes> jpeg_image_;
ThumbnailScore score1_, score2_;
GURL url1_, url2_;
base::Time time_;
@@ -63,21 +66,14 @@ void ThumbnailStoreTest::SetUp() {
// image is the original SkBitmap representing the thumbnail
image_ = *(JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail)));
- // The ThumbnailStore will encode the thumbnail to jpeg at 90% quality, so
- // we do this to image. When image is stored, image_enc_dec_ is what
- // ThumbnailStore should return.
- std::vector<unsigned char> jpeg_data;
SkAutoLockPixels thumbnail_lock(image_);
+ jpeg_image_ = new RefCountedBytes;
bool encoded = JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(image_.getAddr32(0, 0)),
JPEGCodec::FORMAT_BGRA, image_.width(),
image_.height(),
static_cast<int>(image_.rowBytes()), 90,
- &jpeg_data);
-
- image_enc_dec_ = *(JPEGCodec::Decode(
- reinterpret_cast<const unsigned char*>(&jpeg_data[0]),
- jpeg_data.size()));
+ &(jpeg_image_->data));
}
void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) {
@@ -86,15 +82,20 @@ void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) {
// differences should be small since encoding was done at 90% before
// writing to disk.
+ if (image_a->height() != image_b->height() ||
+ image_b->width() != image_b->width() ||
+ image_a->rowBytes() != image_b->rowBytes())
+ return;
+
SkAutoLockPixels lock_a(*image_a);
SkAutoLockPixels lock_b(*image_b);
- int ppr = read_image_.rowBytesAsPixels();
+ int ppr = image_a->rowBytesAsPixels();
unsigned int *a, *b;
unsigned int maxv[4];
memset(maxv, 0, sizeof(maxv));
- for (int nrows = read_image_.height()-1; nrows >= 0; nrows--) {
+ for (int nrows = image_a->height()-1; nrows >= 0; nrows--) {
a = image_a->getAddr32(0, nrows);
b = image_b->getAddr32(0, nrows);
for (int i = 0; i < ppr; i += 4) {
@@ -114,61 +115,47 @@ void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) {
}
TEST_F(ThumbnailStoreTest, RetrieveFromCache) {
- ThumbnailStore* store = new ThumbnailStore;
- store->AddRef();
+ RefCountedBytes* read_image = NULL;
+ scoped_refptr<ThumbnailStore> store = new ThumbnailStore;
+
store->file_path_ = file_path_;
store->cache_.reset(new ThumbnailStore::Cache);
store->cache_initialized_ = true;
- read_image_.reset();
-
// Retrieve a thumbnail/score for a nonexistent page.
- EXPECT_FALSE(store->GetPageThumbnail(url2_, &read_image_, &score2_));
+ EXPECT_FALSE(store->GetPageThumbnail(url2_, &read_image));
// Store a thumbnail into the cache and retrieve it.
EXPECT_TRUE(store->SetPageThumbnail(url1_, image_, score1_, false));
- EXPECT_TRUE(store->GetPageThumbnail(url1_, &read_image_, &score2_));
- EXPECT_TRUE(score1_.Equals(score2_));
- EXPECT_TRUE(read_image_.getSize() == image_.getSize());
- EXPECT_TRUE(read_image_.pixelRef() == image_.pixelRef());
- EXPECT_FALSE(read_image_.isNull());
+ EXPECT_TRUE(store->GetPageThumbnail(url1_, &read_image));
+ EXPECT_TRUE(score1_.Equals((*store->cache_)[url1_].second));
+ EXPECT_TRUE(read_image->data.size() == jpeg_image_->data.size());
+ EXPECT_EQ(0, memcmp(&read_image->data[0], &jpeg_image_->data[0],
+ jpeg_image_->data.size()));
- store->Release();
+ read_image->Release();
}
TEST_F(ThumbnailStoreTest, RetrieveFromDisk) {
- ThumbnailStore* store = new ThumbnailStore;
- store->AddRef();
+ scoped_refptr<RefCountedBytes> read_image = new RefCountedBytes;
+ scoped_refptr<ThumbnailStore> store = new ThumbnailStore;
+
store->file_path_ = file_path_;
store->cache_.reset(new ThumbnailStore::Cache);
store->cache_initialized_ = true;
- read_image_.reset();
-
// Store a thumbnail onto the disk and retrieve it.
EXPECT_TRUE(store->SetPageThumbnail(url1_, image_, score1_, false));
EXPECT_TRUE(store->WriteThumbnailToDisk(url1_));
EXPECT_TRUE(store->GetPageThumbnailFromDisk(
- file_path_.AppendASCII(url1_.host()), &url2_, &read_image_, &score2_));
+ file_path_.AppendASCII(url1_.host()), &url2_, read_image, &score2_));
+ read_image->AddRef();
EXPECT_TRUE(url1_ == url2_);
EXPECT_TRUE(score1_.Equals(score2_));
- EXPECT_TRUE(read_image_.getSize() == image_enc_dec_.getSize());
- EXPECT_FALSE(read_image_.isNull());
-
- // The retrieved SkBitmap should be the same as the original image
- // encoded at 90% quality to jpeg, then decoded.
-
- {
- SkAutoLockPixels lock_a(read_image_);
- SkAutoLockPixels lock_b(image_enc_dec_);
- EXPECT_TRUE(0 == memcmp(read_image_.getPixels(),
- image_enc_dec_.getPixels(),
- read_image_.getSize()));
- }
- PrintPixelDiff(&read_image_, &image_);
-
- store->Release();
+ EXPECT_TRUE(read_image->data.size() == jpeg_image_->data.size());
+ EXPECT_EQ(0, memcmp(&read_image->data[0], &jpeg_image_->data[0],
+ jpeg_image_->data.size()));
}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 219004d..3b65c85 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1379,6 +1379,8 @@
'browser/task_manager_resource_providers.h',
'browser/theme_resources_util.cc',
'browser/theme_resources_util.h',
+ 'browser/thumbnail_store.cc',
+ 'browser/thumbnail_store.h',
'browser/toolbar_model.cc',
'browser/toolbar_model.h',
'browser/user_data_manager.cc',
@@ -3215,6 +3217,7 @@
'browser/history/text_database_manager_unittest.cc',
'browser/history/text_database_unittest.cc',
'browser/history/thumbnail_database_unittest.cc',
+ 'browser/thumbnail_store_unittest.cc',
'browser/history/url_database_unittest.cc',
'browser/history/visit_database_unittest.cc',
'browser/history/visit_tracker_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index a9335ed..48511d3 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -490,4 +490,8 @@ const wchar_t kNoDefaultBrowserCheck[] = L"no-default-browser-check";
// Enables the benchmarking extensions.
const wchar_t kEnableBenchmarking[] = L"enable-benchmarking";
+// Enables using ThumbnailStore instead of ThumbnailDatabase for setting and
+// getting thumbnails for the new tab page.
+const wchar_t kThumbnailStore[] = L"thumbnail-store";
+
} // namespace switches
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 50666c8..8259d72 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -185,6 +185,8 @@ extern const wchar_t kEnableBenchmarking[];
extern const wchar_t kNoDefaultBrowserCheck[];
+extern const wchar_t kThumbnailStore[];
+
} // namespace switches
#endif // CHROME_COMMON_CHROME_SWITCHES_H_
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 40b88dd..56bfc38 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -121,6 +121,11 @@ class TestingProfile : public Profile {
virtual TemplateURLFetcher* GetTemplateURLFetcher() {
return NULL;
}
+
+ virtual ThumbnailStore* GetThumbnailStore() {
+ return NULL;
+ }
+
virtual DownloadManager* GetDownloadManager() {
return NULL;
}
diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj
index 7c91621..f80b539 100644
--- a/chrome/test/unit/unittests.vcproj
+++ b/chrome/test/unit/unittests.vcproj
@@ -814,6 +814,10 @@
>
</File>
<File
+ RelativePath="..\..\browser\thumbnail_store_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\..\browser\history\url_database_unittest.cc"
>
</File>