| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 void* pixels, | 137 void* pixels, |
| 138 size_t row_bytes) { | 138 size_t row_bytes) { |
| 139 if (decode_failed_) | 139 if (decode_failed_) |
| 140 return false; | 140 return false; |
| 141 | 141 |
| 142 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", | 142 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", |
| 143 static_cast<int>(index)); | 143 static_cast<int>(index)); |
| 144 | 144 |
| 145 // This implementation does not support scaling so check the requested size. | 145 // This implementation does not support scaling so check the requested size. |
| 146 SkISize scaled_size = SkISize::Make(info.width(), info.height()); | 146 SkISize scaled_size = SkISize::Make(info.width(), info.height()); |
| 147 ASSERT(full_size_ == scaled_size); | 147 DCHECK(full_size_ == scaled_size); |
| 148 | 148 |
| 149 // It is okay to allocate ref-counted ExternalMemoryAllocator on the stack, | 149 // It is okay to allocate ref-counted ExternalMemoryAllocator on the stack, |
| 150 // because 1) it contains references to memory that will be invalid after | 150 // because 1) it contains references to memory that will be invalid after |
| 151 // returning (i.e. a pointer to |pixels|) and therefore 2) should not live | 151 // returning (i.e. a pointer to |pixels|) and therefore 2) should not live |
| 152 // longer than the call to the current method. | 152 // longer than the call to the current method. |
| 153 ExternalMemoryAllocator external_allocator(info, pixels, row_bytes); | 153 ExternalMemoryAllocator external_allocator(info, pixels, row_bytes); |
| 154 SkBitmap bitmap = TryToResumeDecode(data, all_data_received, index, | 154 SkBitmap bitmap = TryToResumeDecode(data, all_data_received, index, |
| 155 scaled_size, &external_allocator); | 155 scaled_size, &external_allocator); |
| 156 DCHECK(external_allocator.unique()); // Verify we have the only ref-count. | 156 DCHECK(external_allocator.unique()); // Verify we have the only ref-count. |
| 157 | 157 |
| 158 if (bitmap.isNull()) | 158 if (bitmap.isNull()) |
| 159 return false; | 159 return false; |
| 160 | 160 |
| 161 // Check to see if the decoder has written directly to the pixel memory | 161 // Check to see if the decoder has written directly to the pixel memory |
| 162 // provided. If not, make a copy. | 162 // provided. If not, make a copy. |
| 163 ASSERT(bitmap.width() == scaled_size.width()); | 163 DCHECK_EQ(bitmap.width(), scaled_size.width()); |
| 164 ASSERT(bitmap.height() == scaled_size.height()); | 164 DCHECK_EQ(bitmap.height(), scaled_size.height()); |
| 165 SkAutoLockPixels bitmap_lock(bitmap); | 165 SkAutoLockPixels bitmap_lock(bitmap); |
| 166 if (bitmap.getPixels() != pixels) | 166 if (bitmap.getPixels() != pixels) |
| 167 CopyPixels(pixels, row_bytes, bitmap.getPixels(), bitmap.rowBytes(), info); | 167 CopyPixels(pixels, row_bytes, bitmap.getPixels(), bitmap.rowBytes(), info); |
| 168 return true; | 168 return true; |
| 169 } | 169 } |
| 170 | 170 |
| 171 bool ImageFrameGenerator::DecodeToYUV(SegmentReader* data, | 171 bool ImageFrameGenerator::DecodeToYUV(SegmentReader* data, |
| 172 size_t index, | 172 size_t index, |
| 173 const SkISize component_sizes[3], | 173 const SkISize component_sizes[3], |
| 174 void* planes[3], | 174 void* planes[3], |
| 175 const size_t row_bytes[3]) { | 175 const size_t row_bytes[3]) { |
| 176 // TODO (scroggo): The only interesting thing this uses from the | 176 // TODO (scroggo): The only interesting thing this uses from the |
| 177 // ImageFrameGenerator is m_decodeFailed. Move this into | 177 // ImageFrameGenerator is m_decodeFailed. Move this into |
| 178 // DecodingImageGenerator, which is the only class that calls it. | 178 // DecodingImageGenerator, which is the only class that calls it. |
| 179 if (decode_failed_) | 179 if (decode_failed_) |
| 180 return false; | 180 return false; |
| 181 | 181 |
| 182 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeToYUV", "frame index", | 182 TRACE_EVENT1("blink", "ImageFrameGenerator::decodeToYUV", "frame index", |
| 183 static_cast<int>(index)); | 183 static_cast<int>(index)); |
| 184 | 184 |
| 185 if (!planes || !planes[0] || !planes[1] || !planes[2] || !row_bytes || | 185 if (!planes || !planes[0] || !planes[1] || !planes[2] || !row_bytes || |
| 186 !row_bytes[0] || !row_bytes[1] || !row_bytes[2]) { | 186 !row_bytes[0] || !row_bytes[1] || !row_bytes[2]) { |
| 187 return false; | 187 return false; |
| 188 } | 188 } |
| 189 | 189 |
| 190 std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create( | 190 std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create( |
| 191 data, true, ImageDecoder::kAlphaPremultiplied, decoder_color_behavior_); | 191 data, true, ImageDecoder::kAlphaPremultiplied, decoder_color_behavior_); |
| 192 // getYUVComponentSizes was already called and was successful, so | 192 // getYUVComponentSizes was already called and was successful, so |
| 193 // ImageDecoder::create must succeed. | 193 // ImageDecoder::create must succeed. |
| 194 ASSERT(decoder); | 194 DCHECK(decoder); |
| 195 | 195 |
| 196 std::unique_ptr<ImagePlanes> image_planes = | 196 std::unique_ptr<ImagePlanes> image_planes = |
| 197 WTF::MakeUnique<ImagePlanes>(planes, row_bytes); | 197 WTF::MakeUnique<ImagePlanes>(planes, row_bytes); |
| 198 decoder->SetImagePlanes(std::move(image_planes)); | 198 decoder->SetImagePlanes(std::move(image_planes)); |
| 199 | 199 |
| 200 ASSERT(decoder->CanDecodeToYUV()); | 200 DCHECK(decoder->CanDecodeToYUV()); |
| 201 | 201 |
| 202 if (decoder->DecodeToYUV()) { | 202 if (decoder->DecodeToYUV()) { |
| 203 SetHasAlpha(0, false); // YUV is always opaque | 203 SetHasAlpha(0, false); // YUV is always opaque |
| 204 return true; | 204 return true; |
| 205 } | 205 } |
| 206 | 206 |
| 207 ASSERT(decoder->Failed()); | 207 DCHECK(decoder->Failed()); |
| 208 yuv_decoding_failed_ = true; | 208 yuv_decoding_failed_ = true; |
| 209 return false; | 209 return false; |
| 210 } | 210 } |
| 211 | 211 |
| 212 SkBitmap ImageFrameGenerator::TryToResumeDecode( | 212 SkBitmap ImageFrameGenerator::TryToResumeDecode( |
| 213 SegmentReader* data, | 213 SegmentReader* data, |
| 214 bool all_data_received, | 214 bool all_data_received, |
| 215 size_t index, | 215 size_t index, |
| 216 const SkISize& scaled_size, | 216 const SkISize& scaled_size, |
| 217 SkBitmap::Allocator* allocator) { | 217 SkBitmap::Allocator* allocator) { |
| 218 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", | 218 TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", |
| 219 static_cast<int>(index)); | 219 static_cast<int>(index)); |
| 220 | 220 |
| 221 ImageDecoder* decoder = 0; | 221 ImageDecoder* decoder = 0; |
| 222 | 222 |
| 223 // Lock the mutex, so only one thread can use the decoder at once. | 223 // Lock the mutex, so only one thread can use the decoder at once. |
| 224 MutexLocker lock(decode_mutex_); | 224 MutexLocker lock(decode_mutex_); |
| 225 const bool resume_decoding = | 225 const bool resume_decoding = |
| 226 ImageDecodingStore::Instance().LockDecoder(this, full_size_, &decoder); | 226 ImageDecodingStore::Instance().LockDecoder(this, full_size_, &decoder); |
| 227 ASSERT(!resume_decoding || decoder); | 227 DCHECK(!resume_decoding || decoder); |
| 228 | 228 |
| 229 SkBitmap full_size_image; | 229 SkBitmap full_size_image; |
| 230 bool complete = Decode(data, all_data_received, index, &decoder, | 230 bool complete = Decode(data, all_data_received, index, &decoder, |
| 231 &full_size_image, allocator); | 231 &full_size_image, allocator); |
| 232 | 232 |
| 233 if (!decoder) | 233 if (!decoder) |
| 234 return SkBitmap(); | 234 return SkBitmap(); |
| 235 | 235 |
| 236 // If we are not resuming decoding that means the decoder is freshly | 236 // If we are not resuming decoding that means the decoder is freshly |
| 237 // created and we have ownership. If we are resuming decoding then | 237 // created and we have ownership. If we are resuming decoding then |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 } | 287 } |
| 288 has_alpha_[index] = has_alpha; | 288 has_alpha_[index] = has_alpha; |
| 289 } | 289 } |
| 290 | 290 |
| 291 bool ImageFrameGenerator::Decode(SegmentReader* data, | 291 bool ImageFrameGenerator::Decode(SegmentReader* data, |
| 292 bool all_data_received, | 292 bool all_data_received, |
| 293 size_t index, | 293 size_t index, |
| 294 ImageDecoder** decoder, | 294 ImageDecoder** decoder, |
| 295 SkBitmap* bitmap, | 295 SkBitmap* bitmap, |
| 296 SkBitmap::Allocator* allocator) { | 296 SkBitmap::Allocator* allocator) { |
| 297 ASSERT(decode_mutex_.Locked()); | 297 #if DCHECK_IS_ON() |
| 298 DCHECK(decode_mutex_.Locked()); |
| 299 #endif |
| 298 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", | 300 TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", |
| 299 full_size_.width(), "height", full_size_.height()); | 301 full_size_.width(), "height", full_size_.height()); |
| 300 | 302 |
| 301 // Try to create an ImageDecoder if we are not given one. | 303 // Try to create an ImageDecoder if we are not given one. |
| 302 ASSERT(decoder); | 304 DCHECK(decoder); |
| 303 bool new_decoder = false; | 305 bool new_decoder = false; |
| 304 bool should_call_set_data = true; | 306 bool should_call_set_data = true; |
| 305 if (!*decoder) { | 307 if (!*decoder) { |
| 306 new_decoder = true; | 308 new_decoder = true; |
| 307 if (image_decoder_factory_) | 309 if (image_decoder_factory_) |
| 308 *decoder = image_decoder_factory_->Create().release(); | 310 *decoder = image_decoder_factory_->Create().release(); |
| 309 | 311 |
| 310 if (!*decoder) { | 312 if (!*decoder) { |
| 311 *decoder = ImageDecoder::Create(data, all_data_received, | 313 *decoder = ImageDecoder::Create(data, all_data_received, |
| 312 ImageDecoder::kAlphaPremultiplied, | 314 ImageDecoder::kAlphaPremultiplied, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 return false; | 357 return false; |
| 356 | 358 |
| 357 // A cache object is considered complete if we can decode a complete frame. | 359 // A cache object is considered complete if we can decode a complete frame. |
| 358 // Or we have received all data. The image might not be fully decoded in | 360 // Or we have received all data. The image might not be fully decoded in |
| 359 // the latter case. | 361 // the latter case. |
| 360 const bool is_decode_complete = | 362 const bool is_decode_complete = |
| 361 frame->GetStatus() == ImageFrame::kFrameComplete || all_data_received; | 363 frame->GetStatus() == ImageFrame::kFrameComplete || all_data_received; |
| 362 | 364 |
| 363 SkBitmap full_size_bitmap = frame->Bitmap(); | 365 SkBitmap full_size_bitmap = frame->Bitmap(); |
| 364 if (!full_size_bitmap.isNull()) { | 366 if (!full_size_bitmap.isNull()) { |
| 365 ASSERT(full_size_bitmap.width() == full_size_.width() && | 367 DCHECK_EQ(full_size_bitmap.width(), full_size_.width()); |
| 366 full_size_bitmap.height() == full_size_.height()); | 368 DCHECK_EQ(full_size_bitmap.height(), full_size_.height()); |
| 367 SetHasAlpha(index, !full_size_bitmap.isOpaque()); | 369 SetHasAlpha(index, !full_size_bitmap.isOpaque()); |
| 368 } | 370 } |
| 369 | 371 |
| 370 *bitmap = full_size_bitmap; | 372 *bitmap = full_size_bitmap; |
| 371 return is_decode_complete; | 373 return is_decode_complete; |
| 372 } | 374 } |
| 373 | 375 |
| 374 bool ImageFrameGenerator::HasAlpha(size_t index) { | 376 bool ImageFrameGenerator::HasAlpha(size_t index) { |
| 375 MutexLocker lock(alpha_mutex_); | 377 MutexLocker lock(alpha_mutex_); |
| 376 if (index < has_alpha_.size()) | 378 if (index < has_alpha_.size()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 395 // do YUV decoding. | 397 // do YUV decoding. |
| 396 std::unique_ptr<ImagePlanes> dummy_image_planes = | 398 std::unique_ptr<ImagePlanes> dummy_image_planes = |
| 397 WTF::WrapUnique(new ImagePlanes); | 399 WTF::WrapUnique(new ImagePlanes); |
| 398 decoder->SetImagePlanes(std::move(dummy_image_planes)); | 400 decoder->SetImagePlanes(std::move(dummy_image_planes)); |
| 399 | 401 |
| 400 return UpdateYUVComponentSizes(decoder.get(), size_info->fSizes, | 402 return UpdateYUVComponentSizes(decoder.get(), size_info->fSizes, |
| 401 size_info->fWidthBytes); | 403 size_info->fWidthBytes); |
| 402 } | 404 } |
| 403 | 405 |
| 404 } // namespace blink | 406 } // namespace blink |
| OLD | NEW |