OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "cc/resources/video_resource_updater.h" | 5 #include "cc/resources/video_resource_updater.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/bit_cast.h" | 13 #include "base/bit_cast.h" |
14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" |
16 #include "cc/output/gl_renderer.h" | 16 #include "cc/output/gl_renderer.h" |
17 #include "cc/resources/resource_provider.h" | 17 #include "cc/resources/resource_provider.h" |
18 #include "gpu/GLES2/gl2extchromium.h" | 18 #include "gpu/GLES2/gl2extchromium.h" |
19 #include "gpu/command_buffer/client/gles2_interface.h" | 19 #include "gpu/command_buffer/client/gles2_interface.h" |
20 #include "media/base/video_frame.h" | 20 #include "media/base/video_frame.h" |
21 #include "media/renderers/skcanvas_video_renderer.h" | 21 #include "media/renderers/skcanvas_video_renderer.h" |
22 #include "third_party/khronos/GLES2/gl2.h" | 22 #include "third_party/khronos/GLES2/gl2.h" |
23 #include "third_party/khronos/GLES2/gl2ext.h" | 23 #include "third_party/khronos/GLES2/gl2ext.h" |
24 #include "ui/gfx/geometry/size_conversions.h" | 24 #include "ui/gfx/geometry/size_conversions.h" |
25 | 25 |
| 26 #if DCHECK_IS_ON() |
| 27 #include "base/single_thread_task_runner.h" |
| 28 #include "base/thread_task_runner_handle.h" |
| 29 #endif |
| 30 |
26 namespace cc { | 31 namespace cc { |
27 | 32 |
28 namespace { | 33 namespace { |
29 | 34 |
30 const ResourceFormat kRGBResourceFormat = RGBA_8888; | 35 const ResourceFormat kRGBResourceFormat = RGBA_8888; |
31 | 36 |
32 VideoFrameExternalResources::ResourceType ResourceTypeForVideoFrame( | 37 VideoFrameExternalResources::ResourceType ResourceTypeForVideoFrame( |
33 media::VideoFrame* video_frame) { | 38 media::VideoFrame* video_frame) { |
34 switch (video_frame->format()) { | 39 switch (video_frame->format()) { |
35 case media::PIXEL_FORMAT_ARGB: | 40 case media::PIXEL_FORMAT_ARGB: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 sync_token_.Clear(); | 110 sync_token_.Clear(); |
106 } | 111 } |
107 } | 112 } |
108 } | 113 } |
109 | 114 |
110 private: | 115 private: |
111 gpu::gles2::GLES2Interface* gl_; | 116 gpu::gles2::GLES2Interface* gl_; |
112 gpu::SyncToken sync_token_; | 117 gpu::SyncToken sync_token_; |
113 }; | 118 }; |
114 | 119 |
| 120 #if DCHECK_IS_ON() |
| 121 void OnVideoFrameDestruct( |
| 122 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 123 const base::Closure& task) { |
| 124 task_runner->PostTask(FROM_HERE, task); |
| 125 } |
| 126 #endif |
| 127 |
115 } // namespace | 128 } // namespace |
116 | 129 |
117 VideoResourceUpdater::PlaneResource::PlaneResource( | 130 VideoResourceUpdater::PlaneResource::PlaneResource( |
118 unsigned int resource_id, | 131 unsigned int resource_id, |
119 const gfx::Size& resource_size, | 132 const gfx::Size& resource_size, |
120 ResourceFormat resource_format, | 133 ResourceFormat resource_format, |
121 gpu::Mailbox mailbox) | 134 gpu::Mailbox mailbox) |
122 : resource_id(resource_id), | 135 : resource_id(resource_id), |
123 resource_size(resource_size), | 136 resource_size(resource_size), |
124 resource_format(resource_format), | 137 resource_format(resource_format), |
125 mailbox(mailbox), | 138 mailbox(mailbox), |
126 ref_count(0), | 139 ref_count(0), |
127 frame_ptr(nullptr), | 140 frame_ptr(nullptr), |
| 141 #if DCHECK_IS_ON() |
| 142 destructed(false), |
| 143 #endif |
128 plane_index(0u) { | 144 plane_index(0u) { |
129 } | 145 } |
130 | 146 |
131 VideoResourceUpdater::PlaneResource::PlaneResource(const PlaneResource& other) = | 147 VideoResourceUpdater::PlaneResource::PlaneResource(const PlaneResource& other) = |
132 default; | 148 default; |
133 | 149 |
134 bool VideoResourceUpdater::PlaneResourceMatchesUniqueID( | 150 bool VideoResourceUpdater::PlaneResourceMatchesUniqueID( |
135 const PlaneResource& plane_resource, | 151 const PlaneResource& plane_resource, |
136 const media::VideoFrame* video_frame, | 152 const media::VideoFrame* video_frame, |
137 size_t plane_index) { | 153 size_t plane_index) { |
138 return plane_resource.frame_ptr == video_frame && | 154 bool matched = plane_resource.frame_ptr == video_frame && |
139 plane_resource.plane_index == plane_index && | 155 plane_resource.plane_index == plane_index && |
140 plane_resource.timestamp == video_frame->timestamp(); | 156 plane_resource.timestamp == video_frame->timestamp(); |
| 157 #if DCHECK_IS_ON() |
| 158 if ((plane_index == 0) && matched) { |
| 159 DCHECK(!plane_resource.destructed) |
| 160 << "ERROR: reused the destructed resource." |
| 161 << " timestamp = " << plane_resource.timestamp; |
| 162 } |
| 163 #endif |
| 164 return matched; |
141 } | 165 } |
142 | 166 |
143 void VideoResourceUpdater::SetPlaneResourceUniqueId( | 167 void VideoResourceUpdater::SetPlaneResourceUniqueId( |
144 const media::VideoFrame* video_frame, | 168 const media::VideoFrame* video_frame, |
145 size_t plane_index, | 169 size_t plane_index, |
146 PlaneResource* plane_resource) { | 170 PlaneResource* plane_resource) { |
147 plane_resource->frame_ptr = video_frame; | 171 plane_resource->frame_ptr = video_frame; |
148 plane_resource->plane_index = plane_index; | 172 plane_resource->plane_index = plane_index; |
149 plane_resource->timestamp = video_frame->timestamp(); | 173 plane_resource->timestamp = video_frame->timestamp(); |
| 174 #if DCHECK_IS_ON() |
| 175 plane_resource->destructed = false; |
| 176 #endif |
150 } | 177 } |
151 | 178 |
152 VideoFrameExternalResources::VideoFrameExternalResources() | 179 VideoFrameExternalResources::VideoFrameExternalResources() |
153 : type(NONE), | 180 : type(NONE), |
154 read_lock_fences_enabled(false), | 181 read_lock_fences_enabled(false), |
155 offset(0.0f), | 182 offset(0.0f), |
156 multiplier(1.0f) {} | 183 multiplier(1.0f) {} |
157 | 184 |
158 VideoFrameExternalResources::VideoFrameExternalResources( | 185 VideoFrameExternalResources::VideoFrameExternalResources( |
159 const VideoFrameExternalResources& other) = default; | 186 const VideoFrameExternalResources& other) = default; |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 if (!video_renderer_) | 413 if (!video_renderer_) |
387 video_renderer_.reset(new media::SkCanvasVideoRenderer); | 414 video_renderer_.reset(new media::SkCanvasVideoRenderer); |
388 | 415 |
389 ResourceProvider::ScopedWriteLockSoftware lock( | 416 ResourceProvider::ScopedWriteLockSoftware lock( |
390 resource_provider_, plane_resource.resource_id); | 417 resource_provider_, plane_resource.resource_id); |
391 SkCanvas canvas(lock.sk_bitmap()); | 418 SkCanvas canvas(lock.sk_bitmap()); |
392 // This is software path, so canvas and video_frame are always backed | 419 // This is software path, so canvas and video_frame are always backed |
393 // by software. | 420 // by software. |
394 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); | 421 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); |
395 SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource); | 422 SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource); |
| 423 #if DCHECK_IS_ON() |
| 424 // Add VideoFrame destructor callback. |
| 425 video_frame->AddDestructionObserver(base::Bind( |
| 426 &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), |
| 427 base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), |
| 428 base::Unretained(video_frame.get()), |
| 429 video_frame->timestamp()))); |
| 430 #endif |
396 } | 431 } |
397 | 432 |
398 external_resources.software_resources.push_back(plane_resource.resource_id); | 433 external_resources.software_resources.push_back(plane_resource.resource_id); |
399 external_resources.software_release_callback = | 434 external_resources.software_release_callback = |
400 base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id); | 435 base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id); |
401 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 436 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
402 return external_resources; | 437 return external_resources; |
403 } | 438 } |
404 | 439 |
405 for (size_t i = 0; i < plane_resources.size(); ++i) { | 440 for (size_t i = 0; i < plane_resources.size(); ++i) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 video_frame->data(i) + (video_stride_bytes * row); | 516 video_frame->data(i) + (video_stride_bytes * row); |
482 memcpy(dst, src, bytes_per_row); | 517 memcpy(dst, src, bytes_per_row); |
483 } | 518 } |
484 } | 519 } |
485 pixels = &upload_pixels_[0]; | 520 pixels = &upload_pixels_[0]; |
486 } | 521 } |
487 | 522 |
488 resource_provider_->CopyToResource(plane_resource.resource_id, pixels, | 523 resource_provider_->CopyToResource(plane_resource.resource_id, pixels, |
489 resource_size_pixels); | 524 resource_size_pixels); |
490 SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource); | 525 SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource); |
| 526 #if DCHECK_IS_ON() |
| 527 // Add VideoFrame destructor callback. |
| 528 if (i == 0) { |
| 529 video_frame->AddDestructionObserver(base::Bind( |
| 530 &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), |
| 531 base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), |
| 532 base::Unretained(video_frame.get()), |
| 533 video_frame->timestamp()))); |
| 534 } |
| 535 #endif |
491 } | 536 } |
492 | 537 |
493 if (plane_resource.resource_format == LUMINANCE_F16) { | 538 if (plane_resource.resource_format == LUMINANCE_F16) { |
494 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | 539 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the |
495 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). | 540 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). |
496 // | 541 // |
497 // Half-floats are evaluated as: | 542 // Half-floats are evaluated as: |
498 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); | 543 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); |
499 // | 544 // |
500 // In our case the exponent is 14 (since we or with 0x3800) and | 545 // In our case the exponent is 14 (since we or with 0x3800) and |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 if (lost_resource) { | 734 if (lost_resource) { |
690 resource_it->ref_count = 0; | 735 resource_it->ref_count = 0; |
691 updater->DeleteResource(resource_it); | 736 updater->DeleteResource(resource_it); |
692 return; | 737 return; |
693 } | 738 } |
694 | 739 |
695 --resource_it->ref_count; | 740 --resource_it->ref_count; |
696 DCHECK_GE(resource_it->ref_count, 0); | 741 DCHECK_GE(resource_it->ref_count, 0); |
697 } | 742 } |
698 | 743 |
| 744 #if DCHECK_IS_ON() |
| 745 // static |
| 746 void VideoResourceUpdater::MarkOldResource( |
| 747 base::WeakPtr<VideoResourceUpdater> updater, |
| 748 const media::VideoFrame* video_frame_ptr, |
| 749 base::TimeDelta timestamp) { |
| 750 if (!updater) |
| 751 return; |
| 752 const ResourceList::iterator resource_it = std::find_if( |
| 753 updater->all_resources_.begin(), updater->all_resources_.end(), |
| 754 [video_frame_ptr, timestamp](const PlaneResource& plane_resource) { |
| 755 return plane_resource.frame_ptr == video_frame_ptr && |
| 756 plane_resource.timestamp == timestamp && |
| 757 plane_resource.plane_index == 0; |
| 758 }); |
| 759 if (resource_it == updater->all_resources_.end()) |
| 760 return; |
| 761 |
| 762 resource_it->destructed = true; |
| 763 } |
| 764 #endif |
| 765 |
699 } // namespace cc | 766 } // namespace cc |
OLD | NEW |