Chromium Code Reviews| 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 "ui/android/resources/resource_manager_impl.h" | 5 #include "ui/android/resources/resource_manager_impl.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/android/jni_array.h" | 13 #include "base/android/jni_array.h" |
| 14 #include "base/android/jni_string.h" | 14 #include "base/android/jni_string.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/trace_event/memory_dump_manager.h" | 18 #include "base/trace_event/memory_dump_manager.h" |
| 19 #include "base/trace_event/memory_usage_estimator.h" | 19 #include "base/trace_event/memory_usage_estimator.h" |
| 20 #include "base/trace_event/process_memory_dump.h" | 20 #include "base/trace_event/process_memory_dump.h" |
| 21 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 22 #include "cc/resources/scoped_ui_resource.h" | 22 #include "cc/resources/scoped_ui_resource.h" |
| 23 #include "cc/resources/ui_resource_manager.h" | 23 #include "cc/resources/ui_resource_manager.h" |
| 24 #include "jni/ResourceManager_jni.h" | 24 #include "jni/ResourceManager_jni.h" |
| 25 #include "third_party/skia/include/core/SkBitmap.h" | 25 #include "third_party/skia/include/core/SkBitmap.h" |
| 26 #include "third_party/skia/include/core/SkCanvas.h" | 26 #include "third_party/skia/include/core/SkCanvas.h" |
| 27 #include "third_party/skia/include/core/SkColorFilter.h" | 27 #include "third_party/skia/include/core/SkColorFilter.h" |
| 28 #include "ui/android/resources/nine_patch_resource.h" | |
| 28 #include "ui/android/resources/ui_resource_provider.h" | 29 #include "ui/android/resources/ui_resource_provider.h" |
| 29 #include "ui/android/window_android.h" | 30 #include "ui/android/window_android.h" |
| 30 #include "ui/gfx/android/java_bitmap.h" | 31 #include "ui/gfx/android/java_bitmap.h" |
| 31 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" |
| 32 | 33 |
| 33 using base::android::JavaArrayOfIntArrayToIntVector; | 34 using base::android::JavaArrayOfIntArrayToIntVector; |
| 35 using base::android::JavaParamRef; | |
| 34 using base::android::JavaRef; | 36 using base::android::JavaRef; |
| 35 | 37 |
| 36 namespace ui { | 38 namespace ui { |
| 37 | 39 |
| 38 // static | 40 // static |
| 39 ResourceManagerImpl* ResourceManagerImpl::FromJavaObject( | 41 ResourceManagerImpl* ResourceManagerImpl::FromJavaObject( |
| 40 const JavaRef<jobject>& jobj) { | 42 const JavaRef<jobject>& jobj) { |
| 41 return reinterpret_cast<ResourceManagerImpl*>( | 43 return reinterpret_cast<ResourceManagerImpl*>( |
| 42 Java_ResourceManager_getNativePtr(base::android::AttachCurrentThread(), | 44 Java_ResourceManager_getNativePtr(base::android::AttachCurrentThread(), |
| 43 jobj)); | 45 jobj)); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 66 DCHECK(!ui_resource_manager_); | 68 DCHECK(!ui_resource_manager_); |
| 67 DCHECK(ui_resource_manager); | 69 DCHECK(ui_resource_manager); |
| 68 ui_resource_manager_ = ui_resource_manager; | 70 ui_resource_manager_ = ui_resource_manager; |
| 69 } | 71 } |
| 70 | 72 |
| 71 base::android::ScopedJavaLocalRef<jobject> | 73 base::android::ScopedJavaLocalRef<jobject> |
| 72 ResourceManagerImpl::GetJavaObject() { | 74 ResourceManagerImpl::GetJavaObject() { |
| 73 return base::android::ScopedJavaLocalRef<jobject>(java_obj_); | 75 return base::android::ScopedJavaLocalRef<jobject>(java_obj_); |
| 74 } | 76 } |
| 75 | 77 |
| 76 ResourceManager::Resource* ResourceManagerImpl::GetResource( | 78 Resource* ResourceManagerImpl::GetResource(AndroidResourceType res_type, |
| 77 AndroidResourceType res_type, | 79 int res_id) { |
| 78 int res_id) { | |
| 79 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); | 80 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); |
| 80 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); | 81 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); |
| 81 | 82 |
| 82 std::unordered_map<int, std::unique_ptr<Resource>>::iterator item = | 83 std::unordered_map<int, std::unique_ptr<Resource>>::iterator item = |
| 83 resources_[res_type].find(res_id); | 84 resources_[res_type].find(res_id); |
| 84 | 85 |
| 85 if (item == resources_[res_type].end() || | 86 if (item == resources_[res_type].end() || |
| 86 res_type == ANDROID_RESOURCE_TYPE_DYNAMIC || | 87 res_type == ANDROID_RESOURCE_TYPE_DYNAMIC || |
| 87 res_type == ANDROID_RESOURCE_TYPE_DYNAMIC_BITMAP) { | 88 res_type == ANDROID_RESOURCE_TYPE_DYNAMIC_BITMAP) { |
| 88 RequestResourceFromJava(res_type, res_id); | 89 RequestResourceFromJava(res_type, res_id); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 102 // used as defined in |used_tints|. | 103 // used as defined in |used_tints|. |
| 103 for (auto it = tinted_resources_.cbegin(); it != tinted_resources_.cend();) { | 104 for (auto it = tinted_resources_.cbegin(); it != tinted_resources_.cend();) { |
| 104 if (used_tints.find(it->first) == used_tints.end()) { | 105 if (used_tints.find(it->first) == used_tints.end()) { |
| 105 it = tinted_resources_.erase(it); | 106 it = tinted_resources_.erase(it); |
| 106 } else { | 107 } else { |
| 107 ++it; | 108 ++it; |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 } | 111 } |
| 111 | 112 |
| 112 ResourceManager::Resource* ResourceManagerImpl::GetStaticResourceWithTint( | 113 Resource* ResourceManagerImpl::GetStaticResourceWithTint(int res_id, |
| 113 int res_id, | 114 SkColor tint_color) { |
| 114 SkColor tint_color) { | |
| 115 if (tinted_resources_.find(tint_color) == tinted_resources_.end()) { | 115 if (tinted_resources_.find(tint_color) == tinted_resources_.end()) { |
| 116 tinted_resources_[tint_color] = base::MakeUnique<ResourceMap>(); | 116 tinted_resources_[tint_color] = base::MakeUnique<ResourceMap>(); |
| 117 } | 117 } |
| 118 ResourceMap* resource_map = tinted_resources_[tint_color].get(); | 118 ResourceMap* resource_map = tinted_resources_[tint_color].get(); |
| 119 | 119 |
| 120 // If the resource is already cached, use it. | 120 // If the resource is already cached, use it. |
| 121 std::unordered_map<int, std::unique_ptr<Resource>>::iterator item = | 121 std::unordered_map<int, std::unique_ptr<Resource>>::iterator item = |
| 122 resource_map->find(res_id); | 122 resource_map->find(res_id); |
| 123 if (item != resource_map->end()) | 123 if (item != resource_map->end()) |
| 124 return item->second.get(); | 124 return item->second.get(); |
| 125 | 125 |
| 126 std::unique_ptr<Resource> tinted_resource = base::MakeUnique<Resource>(); | 126 Resource* base_image = GetResource(ANDROID_RESOURCE_TYPE_STATIC, res_id); |
| 127 DCHECK(base_image); | |
| 127 | 128 |
| 128 ResourceManager::Resource* base_image = | 129 std::unique_ptr<Resource> tinted_resource = base_image->CreateForCopy(); |
| 129 GetResource(ANDROID_RESOURCE_TYPE_STATIC, res_id); | |
| 130 DCHECK(base_image); | |
| 131 | 130 |
| 132 TRACE_EVENT0("browser", "ResourceManagerImpl::GetStaticResourceWithTint"); | 131 TRACE_EVENT0("browser", "ResourceManagerImpl::GetStaticResourceWithTint"); |
| 133 SkBitmap tinted_bitmap; | 132 SkBitmap tinted_bitmap; |
| 134 tinted_bitmap.allocPixels(SkImageInfo::MakeN32Premul(base_image->size.width(), | 133 tinted_bitmap.allocPixels(SkImageInfo::MakeN32Premul( |
| 135 base_image->size.height())); | 134 base_image->size().width(), base_image->size().height())); |
| 136 | 135 |
| 137 SkCanvas canvas(tinted_bitmap); | 136 SkCanvas canvas(tinted_bitmap); |
| 138 canvas.clear(SK_ColorTRANSPARENT); | 137 canvas.clear(SK_ColorTRANSPARENT); |
| 139 | 138 |
| 140 // Build a color filter to use on the base resource. This filter multiplies | 139 // Build a color filter to use on the base resource. This filter multiplies |
| 141 // the RGB components by the components of the new color but retains the | 140 // the RGB components by the components of the new color but retains the |
| 142 // alpha of the original image. | 141 // alpha of the original image. |
| 143 SkPaint color_filter; | 142 SkPaint color_filter; |
| 144 color_filter.setColorFilter( | 143 color_filter.setColorFilter( |
| 145 SkColorFilter::MakeModeFilter(tint_color, SkBlendMode::kModulate)); | 144 SkColorFilter::MakeModeFilter(tint_color, SkBlendMode::kModulate)); |
| 146 | 145 |
| 147 // Draw the resource and make it immutable. | 146 // Draw the resource and make it immutable. |
| 148 base_image->ui_resource->GetBitmap(base_image->ui_resource->id(), false) | 147 base_image->ui_resource() |
| 148 ->GetBitmap(base_image->ui_resource()->id(), false) | |
| 149 .DrawToCanvas(&canvas, &color_filter); | 149 .DrawToCanvas(&canvas, &color_filter); |
| 150 tinted_bitmap.setImmutable(); | 150 tinted_bitmap.setImmutable(); |
| 151 | 151 |
| 152 // Create a UI resource from the new bitmap. | 152 // Create a UI resource from the new bitmap. |
| 153 tinted_resource->size = gfx::Size(base_image->size); | 153 tinted_resource->SetUIResource( |
| 154 tinted_resource->padding = gfx::Rect(base_image->padding); | 154 cc::ScopedUIResource::Create(ui_resource_manager_, |
| 155 tinted_resource->aperture = gfx::Rect(base_image->aperture); | 155 cc::UIResourceBitmap(tinted_bitmap)), |
| 156 tinted_resource->ui_resource = cc::ScopedUIResource::Create( | 156 base_image->size()); |
| 157 ui_resource_manager_, cc::UIResourceBitmap(tinted_bitmap)); | |
| 158 | 157 |
| 159 (*resource_map)[res_id].swap(tinted_resource); | 158 (*resource_map)[res_id].swap(tinted_resource); |
| 160 | 159 |
| 161 return (*resource_map)[res_id].get(); | 160 return (*resource_map)[res_id].get(); |
| 162 } | 161 } |
| 163 | 162 |
| 164 void ResourceManagerImpl::ClearTintedResourceCache(JNIEnv* env, | 163 void ResourceManagerImpl::ClearTintedResourceCache(JNIEnv* env, |
| 165 const JavaRef<jobject>& jobj) { | 164 const JavaRef<jobject>& jobj) { |
| 166 tinted_resources_.clear(); | 165 tinted_resources_.clear(); |
| 167 } | 166 } |
| 168 | 167 |
| 169 void ResourceManagerImpl::PreloadResource(AndroidResourceType res_type, | 168 void ResourceManagerImpl::PreloadResource(AndroidResourceType res_type, |
| 170 int res_id) { | 169 int res_id) { |
| 171 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); | 170 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); |
| 172 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); | 171 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); |
| 173 | 172 |
| 174 // Don't send out a query if the resource is already loaded. | 173 // Don't send out a query if the resource is already loaded. |
| 175 if (resources_[res_type].find(res_id) != resources_[res_type].end()) | 174 if (resources_[res_type].find(res_id) != resources_[res_type].end()) |
| 176 return; | 175 return; |
| 177 | 176 |
| 178 PreloadResourceFromJava(res_type, res_id); | 177 PreloadResourceFromJava(res_type, res_id); |
| 179 } | 178 } |
| 180 | 179 |
| 181 void ResourceManagerImpl::OnResourceReady(JNIEnv* env, | 180 void ResourceManagerImpl::OnResourceReady(JNIEnv* env, |
| 182 const JavaRef<jobject>& jobj, | 181 const JavaRef<jobject>& jobj, |
| 183 jint res_type, | 182 jint res_type, |
| 184 jint res_id, | 183 jint res_id, |
| 185 const JavaRef<jobject>& bitmap, | 184 const JavaRef<jobject>& bitmap, |
| 186 jint padding_left, | 185 jlong native_resource) { |
| 187 jint padding_top, | |
| 188 jint padding_right, | |
| 189 jint padding_bottom, | |
| 190 jint aperture_left, | |
| 191 jint aperture_top, | |
| 192 jint aperture_right, | |
| 193 jint aperture_bottom) { | |
| 194 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); | 186 DCHECK_GE(res_type, ANDROID_RESOURCE_TYPE_FIRST); |
| 195 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); | 187 DCHECK_LE(res_type, ANDROID_RESOURCE_TYPE_LAST); |
| 196 TRACE_EVENT2("ui", "ResourceManagerImpl::OnResourceReady", | 188 TRACE_EVENT2("ui", "ResourceManagerImpl::OnResourceReady", |
| 197 "resource_type", res_type, | 189 "resource_type", res_type, |
| 198 "resource_id", res_id); | 190 "resource_id", res_id); |
| 199 | 191 |
| 200 std::unordered_map<int, std::unique_ptr<Resource>>::iterator item = | 192 resources_[res_type][res_id] = |
| 201 resources_[res_type].find(res_id); | 193 base::WrapUnique(reinterpret_cast<Resource*>(native_resource)); |
| 202 if (item == resources_[res_type].end()) { | |
|
Khushal
2017/03/09 23:05:37
I was worried about making repeated dynamic alloca
mdjones
2017/03/10 18:12:00
Dynamic resources use the same id when they are up
Khushal
2017/03/10 19:19:24
True, and I assumed these updates are quite rare.
mdjones
2017/03/13 16:47:06
Right, we shouldn't have to worry about this.
| |
| 203 resources_[res_type][res_id] = base::MakeUnique<Resource>(); | |
| 204 } | |
| 205 | |
| 206 Resource* resource = resources_[res_type][res_id].get(); | 194 Resource* resource = resources_[res_type][res_id].get(); |
| 207 | 195 |
| 208 gfx::JavaBitmap jbitmap(bitmap); | 196 gfx::JavaBitmap jbitmap(bitmap); |
| 209 resource->size = jbitmap.size(); | |
| 210 resource->padding.SetRect(padding_left, padding_top, | |
| 211 padding_right - padding_left, | |
| 212 padding_bottom - padding_top); | |
| 213 resource->aperture.SetRect(aperture_left, aperture_top, | |
| 214 aperture_right - aperture_left, | |
| 215 aperture_bottom - aperture_top); | |
| 216 | |
| 217 SkBitmap skbitmap = gfx::CreateSkBitmapFromJavaBitmap(jbitmap); | 197 SkBitmap skbitmap = gfx::CreateSkBitmapFromJavaBitmap(jbitmap); |
| 218 skbitmap.setImmutable(); | 198 skbitmap.setImmutable(); |
| 219 resource->ui_resource = cc::ScopedUIResource::Create( | 199 resource->SetUIResource( |
| 220 ui_resource_manager_, cc::UIResourceBitmap(skbitmap)); | 200 cc::ScopedUIResource::Create(ui_resource_manager_, |
| 201 cc::UIResourceBitmap(skbitmap)), | |
| 202 jbitmap.size()); | |
| 221 } | 203 } |
| 222 | 204 |
| 223 void ResourceManagerImpl::RemoveResource( | 205 void ResourceManagerImpl::RemoveResource( |
| 224 JNIEnv* env, | 206 JNIEnv* env, |
| 225 const base::android::JavaRef<jobject>& jobj, | 207 const base::android::JavaRef<jobject>& jobj, |
| 226 jint res_type, | 208 jint res_type, |
| 227 jint res_id) { | 209 jint res_id) { |
| 228 resources_[res_type].erase(res_id); | 210 resources_[res_type].erase(res_id); |
| 229 } | 211 } |
| 230 | 212 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 int bitmap_res_id, int metadata_res_id, bool reloading) { | 357 int bitmap_res_id, int metadata_res_id, bool reloading) { |
| 376 TRACE_EVENT2("ui", | 358 TRACE_EVENT2("ui", |
| 377 "ResourceManagerImpl::RequestCrushedSpriteResourceFromJava", | 359 "ResourceManagerImpl::RequestCrushedSpriteResourceFromJava", |
| 378 "bitmap_res_id", bitmap_res_id, | 360 "bitmap_res_id", bitmap_res_id, |
| 379 "metadata_res_id", metadata_res_id); | 361 "metadata_res_id", metadata_res_id); |
| 380 Java_ResourceManager_crushedSpriteResourceRequested( | 362 Java_ResourceManager_crushedSpriteResourceRequested( |
| 381 base::android::AttachCurrentThread(), java_obj_, bitmap_res_id, | 363 base::android::AttachCurrentThread(), java_obj_, bitmap_res_id, |
| 382 metadata_res_id, reloading); | 364 metadata_res_id, reloading); |
| 383 } | 365 } |
| 384 | 366 |
| 367 jlong CreateBitmapResource(JNIEnv* env, const JavaParamRef<jclass>& clazz) { | |
| 368 return reinterpret_cast<intptr_t>(new Resource()); | |
| 369 } | |
| 370 | |
| 371 jlong CreateNinePatchBitmapResource(JNIEnv* env, | |
| 372 const JavaParamRef<jclass>& clazz, | |
| 373 jint padding_left, | |
| 374 jint padding_top, | |
| 375 jint padding_right, | |
| 376 jint padding_bottom, | |
| 377 jint aperture_left, | |
| 378 jint aperture_top, | |
| 379 jint aperture_right, | |
| 380 jint aperture_bottom) { | |
| 381 gfx::Rect padding(padding_left, padding_top, padding_right - padding_left, | |
| 382 padding_bottom - padding_top); | |
| 383 gfx::Rect aperture(aperture_left, aperture_top, | |
| 384 aperture_right - aperture_left, | |
| 385 aperture_bottom - aperture_top); | |
| 386 return reinterpret_cast<intptr_t>(new NinePatchResource(padding, aperture)); | |
| 387 } | |
| 388 | |
| 385 } // namespace ui | 389 } // namespace ui |
| OLD | NEW |