| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/thumbnail/thumbnail_cache.h" | 5 #include "chrome/browser/android/thumbnail/thumbnail_cache.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 if (!WriteBigEndianToFile(file, kCompressedKey)) | 495 if (!WriteBigEndianToFile(file, kCompressedKey)) |
| 496 return false; | 496 return false; |
| 497 | 497 |
| 498 if (!WriteBigEndianToFile(file, content_size.width())) | 498 if (!WriteBigEndianToFile(file, content_size.width())) |
| 499 return false; | 499 return false; |
| 500 | 500 |
| 501 if (!WriteBigEndianToFile(file, content_size.height())) | 501 if (!WriteBigEndianToFile(file, content_size.height())) |
| 502 return false; | 502 return false; |
| 503 | 503 |
| 504 // Write ETC1 header. | 504 // Write ETC1 header. |
| 505 compressed_data->lockPixels(); | |
| 506 | |
| 507 unsigned char etc1_buffer[ETC_PKM_HEADER_SIZE]; | 505 unsigned char etc1_buffer[ETC_PKM_HEADER_SIZE]; |
| 508 etc1_pkm_format_header(etc1_buffer, | 506 etc1_pkm_format_header(etc1_buffer, |
| 509 compressed_data->info().width(), | 507 compressed_data->info().width(), |
| 510 compressed_data->info().height()); | 508 compressed_data->info().height()); |
| 511 | 509 |
| 512 int header_bytes_written = file.WriteAtCurrentPos( | 510 int header_bytes_written = file.WriteAtCurrentPos( |
| 513 reinterpret_cast<char*>(etc1_buffer), ETC_PKM_HEADER_SIZE); | 511 reinterpret_cast<char*>(etc1_buffer), ETC_PKM_HEADER_SIZE); |
| 514 if (header_bytes_written != ETC_PKM_HEADER_SIZE) | 512 if (header_bytes_written != ETC_PKM_HEADER_SIZE) |
| 515 return false; | 513 return false; |
| 516 | 514 |
| 517 int data_size = etc1_get_encoded_data_size( | 515 int data_size = etc1_get_encoded_data_size( |
| 518 compressed_data->info().width(), | 516 compressed_data->info().width(), |
| 519 compressed_data->info().height()); | 517 compressed_data->info().height()); |
| 520 int pixel_bytes_written = file.WriteAtCurrentPos( | 518 int pixel_bytes_written = file.WriteAtCurrentPos( |
| 521 reinterpret_cast<char*>(compressed_data->pixels()), | 519 reinterpret_cast<char*>(compressed_data->pixels()), |
| 522 data_size); | 520 data_size); |
| 523 if (pixel_bytes_written != data_size) | 521 if (pixel_bytes_written != data_size) |
| 524 return false; | 522 return false; |
| 525 | 523 |
| 526 compressed_data->unlockPixels(); | |
| 527 | |
| 528 if (!WriteBigEndianToFile(file, kCurrentExtraVersion)) | 524 if (!WriteBigEndianToFile(file, kCurrentExtraVersion)) |
| 529 return false; | 525 return false; |
| 530 | 526 |
| 531 if (!WriteBigEndianFloatToFile(file, 1.f / scale)) | 527 if (!WriteBigEndianFloatToFile(file, 1.f / scale)) |
| 532 return false; | 528 return false; |
| 533 | 529 |
| 534 return true; | 530 return true; |
| 535 } | 531 } |
| 536 | 532 |
| 537 } // anonymous namespace | 533 } // anonymous namespace |
| (...skipping 30 matching lines...) Expand all Loading... |
| 568 | 564 |
| 569 void ThumbnailCache::CompressionTask( | 565 void ThumbnailCache::CompressionTask( |
| 570 SkBitmap raw_data, | 566 SkBitmap raw_data, |
| 571 gfx::Size encoded_size, | 567 gfx::Size encoded_size, |
| 572 const base::Callback<void(sk_sp<SkPixelRef>, const gfx::Size&)>& | 568 const base::Callback<void(sk_sp<SkPixelRef>, const gfx::Size&)>& |
| 573 post_compression_task) { | 569 post_compression_task) { |
| 574 sk_sp<SkPixelRef> compressed_data; | 570 sk_sp<SkPixelRef> compressed_data; |
| 575 gfx::Size content_size; | 571 gfx::Size content_size; |
| 576 | 572 |
| 577 if (!raw_data.empty()) { | 573 if (!raw_data.empty()) { |
| 578 SkAutoLockPixels raw_data_lock(raw_data); | |
| 579 gfx::Size raw_data_size(raw_data.width(), raw_data.height()); | 574 gfx::Size raw_data_size(raw_data.width(), raw_data.height()); |
| 580 size_t pixel_size = 4; // Pixel size is 4 bytes for kARGB_8888_Config. | 575 size_t pixel_size = 4; // Pixel size is 4 bytes for kARGB_8888_Config. |
| 581 size_t stride = pixel_size * raw_data_size.width(); | 576 size_t stride = pixel_size * raw_data_size.width(); |
| 582 | 577 |
| 583 size_t encoded_bytes = | 578 size_t encoded_bytes = |
| 584 etc1_get_encoded_data_size(encoded_size.width(), encoded_size.height()); | 579 etc1_get_encoded_data_size(encoded_size.width(), encoded_size.height()); |
| 585 SkImageInfo info = SkImageInfo::Make(encoded_size.width(), | 580 SkImageInfo info = SkImageInfo::Make(encoded_size.width(), |
| 586 encoded_size.height(), | 581 encoded_size.height(), |
| 587 kUnknown_SkColorType, | 582 kUnknown_SkColorType, |
| 588 kUnpremul_SkAlphaType); | 583 kUnpremul_SkAlphaType); |
| 589 sk_sp<SkData> etc1_pixel_data(SkData::MakeUninitialized(encoded_bytes)); | 584 sk_sp<SkData> etc1_pixel_data(SkData::MakeUninitialized(encoded_bytes)); |
| 590 sk_sp<SkPixelRef> etc1_pixel_ref(SkMallocPixelRef::MakeWithData( | 585 sk_sp<SkPixelRef> etc1_pixel_ref(SkMallocPixelRef::MakeWithData( |
| 591 info, 0, NULL, std::move(etc1_pixel_data))); | 586 info, 0, NULL, std::move(etc1_pixel_data))); |
| 592 | 587 |
| 593 etc1_pixel_ref->lockPixels(); | |
| 594 bool success = etc1_encode_image( | 588 bool success = etc1_encode_image( |
| 595 reinterpret_cast<unsigned char*>(raw_data.getPixels()), | 589 reinterpret_cast<unsigned char*>(raw_data.getPixels()), |
| 596 raw_data_size.width(), | 590 raw_data_size.width(), |
| 597 raw_data_size.height(), | 591 raw_data_size.height(), |
| 598 pixel_size, | 592 pixel_size, |
| 599 stride, | 593 stride, |
| 600 reinterpret_cast<unsigned char*>(etc1_pixel_ref->pixels()), | 594 reinterpret_cast<unsigned char*>(etc1_pixel_ref->pixels()), |
| 601 encoded_size.width(), | 595 encoded_size.width(), |
| 602 encoded_size.height()); | 596 encoded_size.height()); |
| 603 etc1_pixel_ref->setImmutable(); | 597 etc1_pixel_ref->setImmutable(); |
| 604 etc1_pixel_ref->unlockPixels(); | |
| 605 | 598 |
| 606 if (success) { | 599 if (success) { |
| 607 compressed_data = std::move(etc1_pixel_ref); | 600 compressed_data = std::move(etc1_pixel_ref); |
| 608 content_size = raw_data_size; | 601 content_size = raw_data_size; |
| 609 } | 602 } |
| 610 } | 603 } |
| 611 | 604 |
| 612 content::BrowserThread::PostTask( | 605 content::BrowserThread::PostTask( |
| 613 content::BrowserThread::UI, | 606 content::BrowserThread::UI, |
| 614 FROM_HERE, | 607 FROM_HERE, |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 | 846 |
| 854 if (compressed_data.get()) { | 847 if (compressed_data.get()) { |
| 855 gfx::Size buffer_size = gfx::Size(compressed_data->info().width(), | 848 gfx::Size buffer_size = gfx::Size(compressed_data->info().width(), |
| 856 compressed_data->info().height()); | 849 compressed_data->info().height()); |
| 857 | 850 |
| 858 SkBitmap raw_data; | 851 SkBitmap raw_data; |
| 859 raw_data.allocPixels(SkImageInfo::Make(buffer_size.width(), | 852 raw_data.allocPixels(SkImageInfo::Make(buffer_size.width(), |
| 860 buffer_size.height(), | 853 buffer_size.height(), |
| 861 kRGBA_8888_SkColorType, | 854 kRGBA_8888_SkColorType, |
| 862 kOpaque_SkAlphaType)); | 855 kOpaque_SkAlphaType)); |
| 863 SkAutoLockPixels raw_data_lock(raw_data); | |
| 864 compressed_data->lockPixels(); | |
| 865 success = etc1_decode_image( | 856 success = etc1_decode_image( |
| 866 reinterpret_cast<unsigned char*>(compressed_data->pixels()), | 857 reinterpret_cast<unsigned char*>(compressed_data->pixels()), |
| 867 reinterpret_cast<unsigned char*>(raw_data.getPixels()), | 858 reinterpret_cast<unsigned char*>(raw_data.getPixels()), |
| 868 buffer_size.width(), | 859 buffer_size.width(), |
| 869 buffer_size.height(), | 860 buffer_size.height(), |
| 870 raw_data.bytesPerPixel(), | 861 raw_data.bytesPerPixel(), |
| 871 raw_data.rowBytes()); | 862 raw_data.rowBytes()); |
| 872 compressed_data->unlockPixels(); | |
| 873 raw_data.setImmutable(); | 863 raw_data.setImmutable(); |
| 874 | 864 |
| 875 if (!success) { | 865 if (!success) { |
| 876 // Leave raw_data_small empty for consistency with other failure modes. | 866 // Leave raw_data_small empty for consistency with other failure modes. |
| 877 } else if (content_size == buffer_size) { | 867 } else if (content_size == buffer_size) { |
| 878 // Shallow copy the pixel reference. | 868 // Shallow copy the pixel reference. |
| 879 raw_data_small = raw_data; | 869 raw_data_small = raw_data; |
| 880 } else { | 870 } else { |
| 881 // The content size is smaller than the buffer size (likely because of | 871 // The content size is smaller than the buffer size (likely because of |
| 882 // a power-of-two rounding), so deep copy the bitmap. | 872 // a power-of-two rounding), so deep copy the bitmap. |
| 883 raw_data_small.allocPixels(SkImageInfo::Make(content_size.width(), | 873 raw_data_small.allocPixels(SkImageInfo::Make(content_size.width(), |
| 884 content_size.height(), | 874 content_size.height(), |
| 885 kRGBA_8888_SkColorType, | 875 kRGBA_8888_SkColorType, |
| 886 kOpaque_SkAlphaType)); | 876 kOpaque_SkAlphaType)); |
| 887 SkAutoLockPixels raw_data_small_lock(raw_data_small); | |
| 888 SkCanvas small_canvas(raw_data_small); | 877 SkCanvas small_canvas(raw_data_small); |
| 889 small_canvas.drawBitmap(raw_data, 0, 0); | 878 small_canvas.drawBitmap(raw_data, 0, 0); |
| 890 raw_data_small.setImmutable(); | 879 raw_data_small.setImmutable(); |
| 891 } | 880 } |
| 892 } | 881 } |
| 893 | 882 |
| 894 content::BrowserThread::PostTask( | 883 content::BrowserThread::PostTask( |
| 895 content::BrowserThread::UI, | 884 content::BrowserThread::UI, |
| 896 FROM_HERE, | 885 FROM_HERE, |
| 897 base::Bind(post_decompression_callback, success, raw_data_small)); | 886 base::Bind(post_decompression_callback, success, raw_data_small)); |
| 898 } | 887 } |
| 899 | 888 |
| 900 ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData() { | 889 ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData() { |
| 901 } | 890 } |
| 902 | 891 |
| 903 ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData( | 892 ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData( |
| 904 const base::Time& current_time, | 893 const base::Time& current_time, |
| 905 const GURL& url) | 894 const GURL& url) |
| 906 : capture_time_(current_time), url_(url) { | 895 : capture_time_(current_time), url_(url) { |
| 907 } | 896 } |
| 908 | 897 |
| 909 std::pair<SkBitmap, float> ThumbnailCache::CreateApproximation( | 898 std::pair<SkBitmap, float> ThumbnailCache::CreateApproximation( |
| 910 const SkBitmap& bitmap, | 899 const SkBitmap& bitmap, |
| 911 float scale) { | 900 float scale) { |
| 912 DCHECK(!bitmap.empty()); | 901 DCHECK(!bitmap.empty()); |
| 913 DCHECK_GT(scale, 0); | 902 DCHECK_GT(scale, 0); |
| 914 SkAutoLockPixels bitmap_lock(bitmap); | |
| 915 float new_scale = 1.f / kApproximationScaleFactor; | 903 float new_scale = 1.f / kApproximationScaleFactor; |
| 916 | 904 |
| 917 gfx::Size dst_size = gfx::ScaleToFlooredSize( | 905 gfx::Size dst_size = gfx::ScaleToFlooredSize( |
| 918 gfx::Size(bitmap.width(), bitmap.height()), new_scale); | 906 gfx::Size(bitmap.width(), bitmap.height()), new_scale); |
| 919 SkBitmap dst_bitmap; | 907 SkBitmap dst_bitmap; |
| 920 dst_bitmap.allocPixels(SkImageInfo::Make(dst_size.width(), | 908 dst_bitmap.allocPixels(SkImageInfo::Make(dst_size.width(), |
| 921 dst_size.height(), | 909 dst_size.height(), |
| 922 bitmap.info().colorType(), | 910 bitmap.info().colorType(), |
| 923 bitmap.info().alphaType())); | 911 bitmap.info().alphaType())); |
| 924 dst_bitmap.eraseColor(0); | 912 dst_bitmap.eraseColor(0); |
| 925 SkAutoLockPixels dst_bitmap_lock(dst_bitmap); | |
| 926 | |
| 927 SkCanvas canvas(dst_bitmap); | 913 SkCanvas canvas(dst_bitmap); |
| 928 canvas.scale(new_scale, new_scale); | 914 canvas.scale(new_scale, new_scale); |
| 929 canvas.drawBitmap(bitmap, 0, 0, NULL); | 915 canvas.drawBitmap(bitmap, 0, 0, NULL); |
| 930 dst_bitmap.setImmutable(); | 916 dst_bitmap.setImmutable(); |
| 931 | 917 |
| 932 return std::make_pair(dst_bitmap, new_scale * scale); | 918 return std::make_pair(dst_bitmap, new_scale * scale); |
| 933 } | 919 } |
| 934 | 920 |
| 935 void ThumbnailCache::OnMemoryPressure( | 921 void ThumbnailCache::OnMemoryPressure( |
| 936 base::MemoryPressureListener::MemoryPressureLevel level) { | 922 base::MemoryPressureListener::MemoryPressureLevel level) { |
| 937 if (level == base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { | 923 if (level == base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { |
| 938 cache_.Clear(); | 924 cache_.Clear(); |
| 939 approximation_cache_.Clear(); | 925 approximation_cache_.Clear(); |
| 940 } | 926 } |
| 941 } | 927 } |
| OLD | NEW |