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

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

Issue 1139063002: cc: Partial tile update for one-copy raster. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: monocle: fixothertests Created 5 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/one_copy_tile_task_worker_pool.h" 5 #include "cc/resources/one_copy_tile_task_worker_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event.h"
12 #include "base/trace_event/trace_event_argument.h" 12 #include "base/trace_event/trace_event_argument.h"
13 #include "cc/debug/traced_value.h" 13 #include "cc/debug/traced_value.h"
14 #include "cc/resources/raster_buffer.h" 14 #include "cc/resources/raster_buffer.h"
15 #include "cc/resources/resource_pool.h" 15 #include "cc/resources/resource_pool.h"
16 #include "cc/resources/scoped_resource.h" 16 #include "cc/resources/scoped_resource.h"
17 #include "gpu/command_buffer/client/gles2_interface.h" 17 #include "gpu/command_buffer/client/gles2_interface.h"
18 #include "ui/gfx/gpu_memory_buffer.h" 18 #include "ui/gfx/gpu_memory_buffer.h"
19 19
20 namespace cc { 20 namespace cc {
21 namespace { 21 namespace {
22 22
23 class RasterBufferImpl : public RasterBuffer { 23 class RasterBufferImpl : public RasterBuffer {
24 public: 24 public:
25 RasterBufferImpl(OneCopyTileTaskWorkerPool* worker_pool, 25 RasterBufferImpl(OneCopyTileTaskWorkerPool* worker_pool,
26 ResourceProvider* resource_provider, 26 ResourceProvider* resource_provider,
27 ResourcePool* resource_pool, 27 ResourcePool* resource_pool,
28 ResourceFormat resource_format, 28 ResourceFormat resource_format,
29 const Resource* resource) 29 const TileTaskData& data)
30 : worker_pool_(worker_pool), 30 : worker_pool_(worker_pool),
31 resource_provider_(resource_provider), 31 resource_provider_(resource_provider),
32 resource_pool_(resource_pool), 32 resource_pool_(resource_pool),
33 resource_(resource), 33 tile_task_data_(data),
34 raster_resource_( 34 reusing_raster_resource_(true),
35 resource_pool->AcquireResource(resource->size(), resource_format)), 35 sequence_(0) {
36 lock_(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer( 36 raster_resource_ = resource_pool->TryAcquireOldResource(
37 resource_provider_, 37 data.resource->size(), resource_format, data.previous_tile_id);
38 raster_resource_->id())), 38 if (!raster_resource_) {
39 sequence_(0) {} 39 raster_resource_ = resource_pool->AcquireResource(data.resource->size(),
40 resource_format);
41 reusing_raster_resource_ = false;
42
43 previous_raster_resource_ =
44 // XXX Readable.
45 resource_pool->TryAcquireOldBusyResource(
46 data.resource->size(), resource_format, data.previous_tile_id);
47 }
48
49 lock_.reset(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer(
50 resource_provider_, raster_resource_->id()));
51 if (previous_raster_resource_) {
52 previous_lock_.reset(new ResourceProvider::ScopedReadLockGpuMemoryBuffer(
53 resource_provider_, previous_raster_resource_->id()));
54 }
55 }
40 56
41 ~RasterBufferImpl() override { 57 ~RasterBufferImpl() override {
42 // Release write lock in case a copy was never scheduled. 58 // Release write/read lock in case a copy was never scheduled.
43 lock_.reset(); 59 lock_.reset();
60 previous_lock_.reset();
44 61
45 // Make sure any scheduled copy operations are issued before we release the 62 // Make sure any scheduled copy operations are issued before we release the
46 // raster resource. 63 // raster resource.
47 if (sequence_) 64 if (sequence_)
48 worker_pool_->AdvanceLastIssuedCopyTo(sequence_); 65 worker_pool_->AdvanceLastIssuedCopyTo(sequence_);
49 66
50 // Return raster resource to pool so it can be used by another RasterBuffer 67 // Return resources to pool so they can be used by another RasterBuffer
51 // instance. 68 // instance.
52 if (raster_resource_) 69 if (raster_resource_) {
53 resource_pool_->ReleaseResource(raster_resource_.Pass()); 70 resource_pool_->ReleaseResource(raster_resource_.Pass(),
71 tile_task_data_.new_tile_id);
72 }
73 if (previous_raster_resource_) {
74 resource_pool_->ReleaseResource(raster_resource_.Pass(),
75 tile_task_data_.previous_tile_id);
76 }
54 } 77 }
55 78
56 // Overridden from RasterBuffer: 79 // Overridden from RasterBuffer:
57 void Playback(const RasterSource* raster_source, 80 void Playback(const RasterSource* raster_source,
58 const gfx::Rect& rect, 81 const gfx::Rect& rect,
59 float scale) override { 82 float scale) override {
60 sequence_ = worker_pool_->PlaybackAndScheduleCopyOnWorkerThread( 83 sequence_ = worker_pool_->PlaybackAndScheduleCopyOnWorkerThread(
61 lock_.Pass(), raster_resource_.Pass(), resource_, raster_source, rect, 84 reusing_raster_resource_, lock_.Pass(), raster_resource_.Pass(),
62 scale); 85 previous_lock_.Pass(), previous_raster_resource_.Pass(),
86 tile_task_data_, raster_source, rect, scale);
63 } 87 }
64 88
65 private: 89 private:
66 OneCopyTileTaskWorkerPool* worker_pool_; 90 OneCopyTileTaskWorkerPool* worker_pool_;
67 ResourceProvider* resource_provider_; 91 ResourceProvider* resource_provider_;
68 ResourcePool* resource_pool_; 92 ResourcePool* resource_pool_;
69 const Resource* resource_; 93 TileTaskData tile_task_data_;
94 bool reusing_raster_resource_;
70 scoped_ptr<ScopedResource> raster_resource_; 95 scoped_ptr<ScopedResource> raster_resource_;
96 scoped_ptr<ScopedResource> previous_raster_resource_;
71 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> lock_; 97 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> lock_;
98 scoped_ptr<ResourceProvider::ScopedReadLockGpuMemoryBuffer> previous_lock_;
72 CopySequenceNumber sequence_; 99 CopySequenceNumber sequence_;
73 100
74 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); 101 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
75 }; 102 };
76 103
77 // Flush interval when performing copy operations. 104 // Flush interval when performing copy operations.
78 const int kCopyFlushPeriod = 4; 105 const int kCopyFlushPeriod = 4;
79 106
80 // Number of in-flight copy operations to allow. 107 // Number of in-flight copy operations to allow.
81 const int kMaxCopyOperations = 32; 108 const int kMaxCopyOperations = 32;
82 109
83 // Delay been checking for copy operations to complete. 110 // Delay been checking for copy operations to complete.
84 const int kCheckForCompletedCopyOperationsTickRateMs = 1; 111 const int kCheckForCompletedCopyOperationsTickRateMs = 1;
85 112
86 // Number of failed attempts to allow before we perform a check that will 113 // Number of failed attempts to allow before we perform a check that will
87 // wait for copy operations to complete if needed. 114 // wait for copy operations to complete if needed.
88 const int kFailedAttemptsBeforeWaitIfNeeded = 256; 115 const int kFailedAttemptsBeforeWaitIfNeeded = 256;
89 116
90 } // namespace 117 } // namespace
91 118
92 OneCopyTileTaskWorkerPool::CopyOperation::CopyOperation( 119 OneCopyTileTaskWorkerPool::CopyOperation::CopyOperation(
93 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock, 120 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer>
94 scoped_ptr<ScopedResource> src, 121 raster_resource_write_lock,
95 const Resource* dst) 122 scoped_ptr<ScopedResource> raster_resource,
96 : write_lock(write_lock.Pass()), src(src.Pass()), dst(dst) { 123 scoped_ptr<ResourceProvider::ScopedReadLockGpuMemoryBuffer>
124 previous_raster_resource_read_lock,
125 scoped_ptr<ScopedResource> previous_raster_resource,
126 const TileTaskData& data)
127 : raster_resource_write_lock(raster_resource_write_lock.Pass()),
128 raster_resource(raster_resource.Pass()),
129 previous_raster_resource_read_lock(
130 previous_raster_resource_read_lock.Pass()),
131 previous_raster_resource(previous_raster_resource.Pass()),
132 tile_task_data(data) {
97 } 133 }
98 134
99 OneCopyTileTaskWorkerPool::CopyOperation::~CopyOperation() { 135 OneCopyTileTaskWorkerPool::CopyOperation::~CopyOperation() {
100 } 136 }
101 137
102 // static 138 // static
103 scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( 139 scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create(
104 base::SequencedTaskRunner* task_runner, 140 base::SequencedTaskRunner* task_runner,
105 TaskGraphRunner* task_graph_runner, 141 TaskGraphRunner* task_graph_runner,
106 ContextProvider* context_provider, 142 ContextProvider* context_provider,
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 task->RunReplyOnOriginThread(); 291 task->RunReplyOnOriginThread();
256 } 292 }
257 completed_tasks_.clear(); 293 completed_tasks_.clear();
258 } 294 }
259 295
260 ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat() { 296 ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat() {
261 return resource_provider_->best_texture_format(); 297 return resource_provider_->best_texture_format();
262 } 298 }
263 299
264 scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster( 300 scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster(
265 const Resource* resource) { 301 const TileTaskData& data) {
266 DCHECK_EQ(resource->format(), resource_provider_->best_texture_format()); 302 DCHECK_EQ(data.resource->format(), resource_provider_->best_texture_format());
267 return make_scoped_ptr<RasterBuffer>( 303 return make_scoped_ptr<RasterBuffer>(
268 new RasterBufferImpl(this, resource_provider_, resource_pool_, 304 new RasterBufferImpl(this, resource_provider_, resource_pool_,
269 resource_provider_->best_texture_format(), 305 resource_provider_->best_texture_format(), data));
270 resource));
271 } 306 }
272 307
273 void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster( 308 void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster(
274 scoped_ptr<RasterBuffer> buffer) { 309 scoped_ptr<RasterBuffer> buffer) {
275 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. 310 // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
276 } 311 }
277 312
278 CopySequenceNumber 313 CopySequenceNumber
279 OneCopyTileTaskWorkerPool::PlaybackAndScheduleCopyOnWorkerThread( 314 OneCopyTileTaskWorkerPool::PlaybackAndScheduleCopyOnWorkerThread(
280 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock, 315 bool reusing_raster_resource,
281 scoped_ptr<ScopedResource> src, 316 scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer>
282 const Resource* dst, 317 raster_resource_write_lock,
318 scoped_ptr<ScopedResource> raster_resource,
319 scoped_ptr<ResourceProvider::ScopedReadLockGpuMemoryBuffer>
320 previous_raster_resource_read_lock,
321 scoped_ptr<ScopedResource> previous_raster_resource,
322 const TileTaskData& tile_task_data,
283 const RasterSource* raster_source, 323 const RasterSource* raster_source,
284 const gfx::Rect& rect, 324 const gfx::Rect& rect,
285 float scale) { 325 float scale) {
326 DCHECK_IMPLIES(reusing_raster_resource, !previous_raster_resource_read_lock);
286 base::AutoLock lock(lock_); 327 base::AutoLock lock(lock_);
287 328
288 int failed_attempts = 0; 329 int failed_attempts = 0;
289 while ((scheduled_copy_operation_count_ + issued_copy_operation_count_) >= 330 while ((scheduled_copy_operation_count_ + issued_copy_operation_count_) >=
290 kMaxCopyOperations) { 331 kMaxCopyOperations) {
291 // Ignore limit when shutdown is set. 332 // Ignore limit when shutdown is set.
292 if (shutdown_) 333 if (shutdown_)
293 break; 334 break;
294 335
295 ++failed_attempts; 336 ++failed_attempts;
(...skipping 16 matching lines...) Expand all
312 353
313 // Increment |scheduled_copy_operation_count_| before releasing |lock_|. 354 // Increment |scheduled_copy_operation_count_| before releasing |lock_|.
314 ++scheduled_copy_operation_count_; 355 ++scheduled_copy_operation_count_;
315 356
316 // There may be more work available, so wake up another worker thread. 357 // There may be more work available, so wake up another worker thread.
317 copy_operation_count_cv_.Signal(); 358 copy_operation_count_cv_.Signal();
318 359
319 { 360 {
320 base::AutoUnlock unlock(lock_); 361 base::AutoUnlock unlock(lock_);
321 362
322 gfx::GpuMemoryBuffer* gpu_memory_buffer = write_lock->GetGpuMemoryBuffer(); 363 gfx::GpuMemoryBuffer* gpu_memory_buffer =
364 raster_resource_write_lock->GetGpuMemoryBuffer();
323 if (gpu_memory_buffer) { 365 if (gpu_memory_buffer) {
324 void* data = NULL; 366 void* raster_data = nullptr;
325 bool rv = gpu_memory_buffer->Map(&data); 367 bool rv = gpu_memory_buffer->Map(&raster_data);
326 DCHECK(rv); 368 DCHECK(rv);
327 int stride; 369 int stride;
328 gpu_memory_buffer->GetStride(&stride); 370 gpu_memory_buffer->GetStride(&stride);
329 TileTaskWorkerPool::PlaybackToMemory(data, src->format(), src->size(), 371
330 stride, raster_source, rect, scale); 372 // If the |raster_resource| is already from the previous version then
373 // there's nothing we need to copy. But otherwise we try copy from the
374 // |previous_raster_resource| to |raster_resource| to reuse raster work if
375 // possible.
376 bool do_partial_update = reusing_raster_resource;
377 if (previous_raster_resource) {
378 gfx::GpuMemoryBuffer* previous_gpu_memory_buffer =
379 previous_raster_resource_read_lock->GetGpuMemoryBuffer();
380 if (previous_gpu_memory_buffer) {
381 void* previous_data = nullptr;
382 bool prv = previous_gpu_memory_buffer->Map(&previous_data);
383 DCHECK(prv);
384 int previous_stride;
385 previous_gpu_memory_buffer->GetStride(&previous_stride);
386
387 if (previous_stride == stride) {
388 DCHECK(rect.size() == raster_resource->size());
389 DCHECK(raster_resource->size() == previous_raster_resource->size());
390 DCHECK(raster_resource->format() ==
391 previous_raster_resource->format());
392 gfx::Rect copy_area = rect;
393 copy_area.Subtract(tile_task_data.raster_dirty_rect);
394 uint8_t* previous_row = static_cast<uint8_t*>(previous_data);
395 uint8_t* raster_row = static_cast<uint8_t*>(raster_data);
396 int bytes_per_pixel =
397 BitsPerPixel(previous_raster_resource->format()) / 8;
398 int row_offset = copy_area.x() * bytes_per_pixel;
399 int bytes_per_row = copy_area.width() * bytes_per_pixel;
400 int rows = copy_area.height();
401 for (int y = copy_area.y(); y < rows; ++y) {
402 memcpy(raster_row + row_offset, previous_row + row_offset,
403 bytes_per_row);
404 raster_row += stride;
405 previous_row += previous_stride;
406 }
407 do_partial_update = true;
408 }
409 previous_gpu_memory_buffer->Unmap();
410 }
411 }
412
413 gfx::Rect playback_rect = rect;
414 if (do_partial_update)
415 playback_rect.Intersect(tile_task_data.raster_dirty_rect);
416 DCHECK(!playback_rect.IsEmpty())
417 << "Why are we rastering a tile that's not dirty?";
418 TileTaskWorkerPool::PlaybackToMemory(
419 raster_data, raster_resource->format(), raster_resource->size(),
420 stride, raster_source, rect, playback_rect, scale);
331 gpu_memory_buffer->Unmap(); 421 gpu_memory_buffer->Unmap();
332 } 422 }
333 } 423 }
334 424
335 pending_copy_operations_.push_back( 425 pending_copy_operations_.push_back(make_scoped_ptr(new CopyOperation(
336 make_scoped_ptr(new CopyOperation(write_lock.Pass(), src.Pass(), dst))); 426 raster_resource_write_lock.Pass(), raster_resource.Pass(),
427 previous_raster_resource_read_lock.Pass(),
428 previous_raster_resource.Pass(), tile_task_data)));
337 429
338 // Acquire a sequence number for this copy operation. 430 // Acquire a sequence number for this copy operation.
339 CopySequenceNumber sequence = next_copy_operation_sequence_++; 431 CopySequenceNumber sequence = next_copy_operation_sequence_++;
340 432
341 // Post task that will advance last flushed copy operation to |sequence| 433 // Post task that will advance last flushed copy operation to |sequence|
342 // if we have reached the flush period. 434 // if we have reached the flush period.
343 if ((sequence % kCopyFlushPeriod) == 0) { 435 if ((sequence % kCopyFlushPeriod) == 0) {
344 task_runner_->PostTask( 436 task_runner_->PostTask(
345 FROM_HERE, 437 FROM_HERE,
346 base::Bind(&OneCopyTileTaskWorkerPool::AdvanceLastFlushedCopyTo, 438 base::Bind(&OneCopyTileTaskWorkerPool::AdvanceLastFlushedCopyTo,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 // operations from "pending" to "issued" state. 497 // operations from "pending" to "issued" state.
406 DCHECK_GE(scheduled_copy_operation_count_, copy_operations.size()); 498 DCHECK_GE(scheduled_copy_operation_count_, copy_operations.size());
407 scheduled_copy_operation_count_ -= copy_operations.size(); 499 scheduled_copy_operation_count_ -= copy_operations.size();
408 issued_copy_operation_count_ += copy_operations.size(); 500 issued_copy_operation_count_ += copy_operations.size();
409 } 501 }
410 502
411 while (!copy_operations.empty()) { 503 while (!copy_operations.empty()) {
412 scoped_ptr<CopyOperation> copy_operation = copy_operations.take_front(); 504 scoped_ptr<CopyOperation> copy_operation = copy_operations.take_front();
413 505
414 // Remove the write lock. 506 // Remove the write lock.
415 copy_operation->write_lock.reset(); 507 copy_operation->raster_resource_write_lock.reset();
416 508
417 // Copy contents of source resource to destination resource. 509 // Copy contents of source resource to destination resource.
418 resource_provider_->CopyResource(copy_operation->src->id(), 510 resource_provider_->CopyResource(
419 copy_operation->dst->id()); 511 copy_operation->raster_resource->id(),
512 copy_operation->tile_task_data.resource->id());
420 513
421 // Return source resource to pool where it can be reused once copy 514 // Return source resource to pool where it can be reused once copy
422 // operation has completed and resource is no longer busy. 515 // operation has completed and resource is no longer busy.
423 resource_pool_->ReleaseResource(copy_operation->src.Pass()); 516 resource_pool_->ReleaseResource(copy_operation->raster_resource.Pass(),
517 copy_operation->tile_task_data.new_tile_id);
518 if (copy_operation->previous_raster_resource) {
519 resource_pool_->ReleaseResource(
520 copy_operation->previous_raster_resource.Pass(),
521 copy_operation->tile_task_data.previous_tile_id);
522 }
424 } 523 }
425 } 524 }
426 525
427 void OneCopyTileTaskWorkerPool:: 526 void OneCopyTileTaskWorkerPool::
428 ScheduleCheckForCompletedCopyOperationsWithLockAcquired( 527 ScheduleCheckForCompletedCopyOperationsWithLockAcquired(
429 bool wait_if_needed) { 528 bool wait_if_needed) {
430 lock_.AssertAcquired(); 529 lock_.AssertAcquired();
431 530
432 if (check_for_completed_copy_operations_pending_) 531 if (check_for_completed_copy_operations_pending_)
433 return; 532 return;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 resource_pool_->total_memory_usage_bytes()); 601 resource_pool_->total_memory_usage_bytes());
503 staging_state->SetInteger("pending_copy_count", 602 staging_state->SetInteger("pending_copy_count",
504 resource_pool_->total_resource_count() - 603 resource_pool_->total_resource_count() -
505 resource_pool_->acquired_resource_count()); 604 resource_pool_->acquired_resource_count());
506 staging_state->SetInteger("bytes_pending_copy", 605 staging_state->SetInteger("bytes_pending_copy",
507 resource_pool_->total_memory_usage_bytes() - 606 resource_pool_->total_memory_usage_bytes() -
508 resource_pool_->acquired_memory_usage_bytes()); 607 resource_pool_->acquired_memory_usage_bytes());
509 } 608 }
510 609
511 } // namespace cc 610 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698