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

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: Rebase and address danakj's comments. 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
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698