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 !defined(NDEBUG) | |
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 !defined(NDEBUG) | |
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 !defined(NDEBUG) | |
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 !defined(NDEBUG) | |
158 if ((plane_index == 0) && matched) { | |
159 DCHECK(!plane_resource.destructed) | |
danakj
2016/03/14 18:52:41
Can you maybe just add a Lock to the struct when d
xjz
2016/03/15 21:04:00
Using Lock needs to add Lock on |all_resource_| an
| |
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 !defined(NDEBUG) | |
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 if (!video_renderer_) | 414 if (!video_renderer_) |
388 video_renderer_.reset(new media::SkCanvasVideoRenderer); | 415 video_renderer_.reset(new media::SkCanvasVideoRenderer); |
389 | 416 |
390 ResourceProvider::ScopedWriteLockSoftware lock( | 417 ResourceProvider::ScopedWriteLockSoftware lock( |
391 resource_provider_, plane_resource.resource_id); | 418 resource_provider_, plane_resource.resource_id); |
392 SkCanvas canvas(lock.sk_bitmap()); | 419 SkCanvas canvas(lock.sk_bitmap()); |
393 // This is software path, so canvas and video_frame are always backed | 420 // This is software path, so canvas and video_frame are always backed |
394 // by software. | 421 // by software. |
395 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); | 422 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); |
396 SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource); | 423 SetPlaneResourceUniqueId(video_frame.get(), 0, &plane_resource); |
424 #if !defined(NDEBUG) | |
425 // Add VideoFrame destructor callback. | |
426 video_frame->AddDestructionObserver(base::Bind( | |
427 &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), | |
428 base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), | |
429 static_cast<void*>(video_frame.get()), | |
430 video_frame->timestamp()))); | |
431 #endif | |
397 } | 432 } |
398 | 433 |
399 external_resources.software_resources.push_back(plane_resource.resource_id); | 434 external_resources.software_resources.push_back(plane_resource.resource_id); |
400 external_resources.software_release_callback = | 435 external_resources.software_release_callback = |
401 base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id); | 436 base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id); |
402 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 437 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
403 return external_resources; | 438 return external_resources; |
404 } | 439 } |
405 | 440 |
406 for (size_t i = 0; i < plane_resources.size(); ++i) { | 441 for (size_t i = 0; i < plane_resources.size(); ++i) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 video_frame->data(i) + (video_stride_bytes * row); | 517 video_frame->data(i) + (video_stride_bytes * row); |
483 memcpy(dst, src, bytes_per_row); | 518 memcpy(dst, src, bytes_per_row); |
484 } | 519 } |
485 } | 520 } |
486 pixels = &upload_pixels_[0]; | 521 pixels = &upload_pixels_[0]; |
487 } | 522 } |
488 | 523 |
489 resource_provider_->CopyToResource(plane_resource.resource_id, pixels, | 524 resource_provider_->CopyToResource(plane_resource.resource_id, pixels, |
490 resource_size_pixels); | 525 resource_size_pixels); |
491 SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource); | 526 SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource); |
527 #if !defined(NDEBUG) | |
528 // Add VideoFrame destructor callback. | |
529 if (i == 0) { | |
530 video_frame->AddDestructionObserver(base::Bind( | |
danakj
2016/03/14 18:52:41
Since you're doing this at each call to SetPlaneRe
xjz
2016/03/15 21:04:00
In that way, we have to add a parameter to SetPlan
danakj
2016/03/17 00:00:34
OK. I feel like there's some refactoring needs bui
| |
531 &OnVideoFrameDestruct, base::ThreadTaskRunnerHandle::Get(), | |
532 base::Bind(&VideoResourceUpdater::MarkOldResource, AsWeakPtr(), | |
533 static_cast<void*>(video_frame.get()), | |
534 video_frame->timestamp()))); | |
535 } | |
536 #endif | |
492 } | 537 } |
493 | 538 |
494 if (plane_resource.resource_format == LUMINANCE_F16) { | 539 if (plane_resource.resource_format == LUMINANCE_F16) { |
495 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | 540 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the |
496 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). | 541 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). |
497 // | 542 // |
498 // Half-floats are evaluated as: | 543 // Half-floats are evaluated as: |
499 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); | 544 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); |
500 // | 545 // |
501 // In our case the exponent is 14 (since we or with 0x3800) and | 546 // In our case the exponent is 14 (since we or with 0x3800) and |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 if (lost_resource) { | 731 if (lost_resource) { |
687 resource_it->ref_count = 0; | 732 resource_it->ref_count = 0; |
688 updater->DeleteResource(resource_it); | 733 updater->DeleteResource(resource_it); |
689 return; | 734 return; |
690 } | 735 } |
691 | 736 |
692 --resource_it->ref_count; | 737 --resource_it->ref_count; |
693 DCHECK_GE(resource_it->ref_count, 0); | 738 DCHECK_GE(resource_it->ref_count, 0); |
694 } | 739 } |
695 | 740 |
741 #if !defined(NDEBUG) | |
742 // static | |
743 void VideoResourceUpdater::MarkOldResource( | |
744 base::WeakPtr<VideoResourceUpdater> updater, | |
745 const void* video_frame_ptr, | |
danakj
2016/03/14 18:52:41
why void?
xjz
2016/03/15 21:04:00
Because it is not allowed to bine a ref counted pt
| |
746 base::TimeDelta timestamp) { | |
747 if (!updater) | |
748 return; | |
749 const ResourceList::iterator resource_it = std::find_if( | |
750 updater->all_resources_.begin(), updater->all_resources_.end(), | |
751 [video_frame_ptr, timestamp](const PlaneResource& plane_resource) { | |
752 return plane_resource.frame_ptr == video_frame_ptr && | |
753 plane_resource.timestamp == timestamp && | |
754 plane_resource.plane_index == 0; | |
755 }); | |
756 if (resource_it == updater->all_resources_.end()) | |
757 return; | |
758 | |
759 resource_it->destructed = true; | |
760 } | |
761 #endif | |
762 | |
696 } // namespace cc | 763 } // namespace cc |
OLD | NEW |