Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: cc/resources/video_resource_updater.cc

Issue 1688033005: Monitor VideoResourceUpdater reusing destructed resource in Debug mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add VideoFrame destructor callback in Debug mode. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 == false)
miu 2016/03/09 01:59:49 nit: DCHECK(!plane_resource.destructed)
xjz 2016/03/10 01:51:44 Done.
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
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
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(
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
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,
746 base::TimeDelta timestamp) {
747 if (!updater.get())
miu 2016/03/09 01:59:49 nit: if (!updater)
xjz 2016/03/10 01:51:44 Done.
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
OLDNEW
« cc/resources/video_resource_updater.h ('K') | « cc/resources/video_resource_updater.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698