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

Side by Side Diff: content/renderer/gpu/compositor_software_output_device.cc

Issue 13042012: Browser side changes for software compositing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 "content/renderer/gpu/compositor_software_output_device.h" 5 #include "content/renderer/gpu/compositor_software_output_device.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "cc/output/software_frame_data.h" 8 #include "cc/output/software_frame_data.h"
9 #include "third_party/skia/include/core/SkCanvas.h" 9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "third_party/skia/include/core/SkDevice.h" 10 #include "third_party/skia/include/core/SkDevice.h"
(...skipping 14 matching lines...) Expand all
25 return dib->id() == id_; 25 return dib->id() == id_;
26 } 26 }
27 27
28 private: 28 private:
29 TransportDIB::Id id_; 29 TransportDIB::Id id_;
30 }; 30 };
31 31
32 } // namespace 32 } // namespace
33 33
34 CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice() 34 CompositorSoftwareOutputDevice::CompositorSoftwareOutputDevice()
35 : front_buffer_(0), 35 : front_buffer_(-1),
36 last_buffer_(-1),
37 num_free_buffers_(0), 36 num_free_buffers_(0),
38 sequence_num_(0) { 37 sequence_num_(0) {
39 DetachFromThread(); 38 DetachFromThread();
40 } 39 }
41 40
42 CompositorSoftwareOutputDevice::~CompositorSoftwareOutputDevice() { 41 CompositorSoftwareOutputDevice::~CompositorSoftwareOutputDevice() {
43 DCHECK(CalledOnValidThread()); 42 DCHECK(CalledOnValidThread());
44 } 43 }
45 44
46 TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() { 45 TransportDIB* CompositorSoftwareOutputDevice::CreateDIB() {
47 const size_t size = 4 * viewport_size_.GetArea(); 46 const size_t size = 4 * viewport_size_.GetArea();
48 TransportDIB* dib = TransportDIB::Create(size, sequence_num_++); 47 TransportDIB* dib = TransportDIB::Create(size, sequence_num_++);
49 CHECK(dib); 48 CHECK(dib);
50 bool success = dib->Map(); 49 bool success = dib->Map();
51 CHECK(success); 50 CHECK(success);
52 return dib; 51 return dib;
53 } 52 }
54 53
55 void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) { 54 void CompositorSoftwareOutputDevice::Resize(gfx::Size viewport_size) {
56 DCHECK(CalledOnValidThread()); 55 DCHECK(CalledOnValidThread());
57 56
58 // Reset last_buffer_ so that we don't copy over old damage.
59 last_buffer_ = -1;
60
61 if (viewport_size_ == viewport_size) 57 if (viewport_size_ == viewport_size)
62 return; 58 return;
63 viewport_size_ = viewport_size;
64 59
65 // Keep non-acked dibs open. 60 // Keep non-ACKed dibs open.
66 for (size_t i = 0; i < dibs_.size() - num_free_buffers_; ++i) { 61 int first_non_free = front_buffer_ + num_free_buffers_ + 1;
67 size_t index = (front_buffer_ + num_free_buffers_ + i) % dibs_.size(); 62 int num_non_free = dibs_.size() - num_free_buffers_;
63 for (int i = 0; i < num_non_free; ++i) {
64 int index = (first_non_free + i) % dibs_.size();
68 awaiting_ack_.push_back(dibs_[index]); 65 awaiting_ack_.push_back(dibs_[index]);
69 dibs_[index] = NULL; 66 dibs_[index] = NULL;
70 } 67 }
71 68
72 dibs_.clear(); 69 dibs_.clear();
73 front_buffer_ = 0; 70 front_buffer_ = -1;
74 num_free_buffers_ = 0; 71 num_free_buffers_ = 0;
72 viewport_size_ = viewport_size;
75 } 73 }
76 74
77 SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) { 75 SkCanvas* CompositorSoftwareOutputDevice::BeginPaint(gfx::Rect damage_rect) {
78 DCHECK(CalledOnValidThread()); 76 DCHECK(CalledOnValidThread());
79 77
78 gfx::Rect last_damage_rect = damage_rect_;
79 damage_rect_ = damage_rect;
80
81 int last_buffer = front_buffer_;
80 if (num_free_buffers_ == 0) { 82 if (num_free_buffers_ == 0) {
81 dibs_.insert(dibs_.begin() + front_buffer_, CreateDIB()); 83 dibs_.insert(dibs_.begin() + (front_buffer_ + 1), CreateDIB());
82 num_free_buffers_++; 84 last_damage_rect = gfx::Rect(viewport_size_);
85 } else {
86 --num_free_buffers_;
83 } 87 }
88 front_buffer_ = (front_buffer_ + 1) % dibs_.size();
84 89
85 TransportDIB* front_dib = dibs_[front_buffer_]; 90 TransportDIB* front_dib = dibs_[front_buffer_];
86 DCHECK(front_dib); 91 DCHECK(front_dib);
87 DCHECK(front_dib->memory()); 92 DCHECK(front_dib->memory());
88 93
89 // Set up a canvas for the front_dib. 94 // Set up a canvas for the current front buffer.
90 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 95 bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
91 viewport_size_.width(), 96 viewport_size_.width(),
92 viewport_size_.height()); 97 viewport_size_.height());
93 bitmap_.setPixels(front_dib->memory()); 98 bitmap_.setPixels(front_dib->memory());
94 device_ = skia::AdoptRef(new SkDevice(bitmap_)); 99 device_ = skia::AdoptRef(new SkDevice(bitmap_));
95 canvas_ = skia::AdoptRef(new SkCanvas(device_.get())); 100 canvas_ = skia::AdoptRef(new SkCanvas(device_.get()));
96 101
97 // Copy damage_rect_ from last_buffer_ to front_buffer_. 102 // Copy over previous damage.
98 if (last_buffer_ != -1 && !damage_rect.Contains(damage_rect_)) { 103 if (last_buffer != -1) {
99 TransportDIB* last_dib = dibs_[last_buffer_]; 104 TransportDIB* last_dib = dibs_[last_buffer];
100 SkBitmap back_bitmap; 105 SkBitmap back_bitmap;
101 back_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 106 back_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
102 viewport_size_.width(), 107 viewport_size_.width(),
103 viewport_size_.height()); 108 viewport_size_.height());
104 back_bitmap.setPixels(last_dib->memory()); 109 back_bitmap.setPixels(last_dib->memory());
105 110
106 SkRect last_damage = gfx::RectToSkRect(damage_rect_); 111 SkRegion region(RectToSkIRect(last_damage_rect));
107 canvas_->drawBitmapRectToRect(back_bitmap, &last_damage, last_damage, NULL); 112 region.op(RectToSkIRect(damage_rect), SkRegion::kDifference_Op);
113 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
114 const SkIRect& src_rect = it.rect();
115 SkRect dst_rect = SkRect::Make(src_rect);
116 canvas_->drawBitmapRect(back_bitmap, &src_rect, dst_rect, NULL);
117 }
108 } 118 }
109 damage_rect_ = damage_rect;
110 119
111 return canvas_.get(); 120 return canvas_.get();
112 } 121 }
113 122
114 void CompositorSoftwareOutputDevice::EndPaint( 123 void CompositorSoftwareOutputDevice::EndPaint(
115 cc::SoftwareFrameData* frame_data) { 124 cc::SoftwareFrameData* frame_data) {
116 DCHECK(CalledOnValidThread()); 125 DCHECK(CalledOnValidThread());
117 126
118 if (frame_data) { 127 if (frame_data) {
119 frame_data->size = viewport_size_; 128 frame_data->size = viewport_size_;
120 frame_data->damage_rect = damage_rect_; 129 frame_data->damage_rect = damage_rect_;
121 frame_data->dib_id = dibs_[front_buffer_]->id(); 130 frame_data->dib_id = dibs_[front_buffer_]->id();
122 } 131 }
123
124 last_buffer_ = front_buffer_;
125 front_buffer_ = (front_buffer_ + 1) % dibs_.size();
126 --num_free_buffers_;
127 DCHECK_GE(num_free_buffers_, 0);
128 } 132 }
129 133
130 void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) { 134 void CompositorSoftwareOutputDevice::ReclaimDIB(const TransportDIB::Id& id) {
131 DCHECK(CalledOnValidThread()); 135 DCHECK(CalledOnValidThread());
132 136
133 // The reclaimed handle might not be among the currently 137 if (!TransportDIB::is_valid_id(id))
138 return;
139
140 // The reclaimed dib id might not be among the currently
134 // active dibs if we got a resize event in the mean time. 141 // active dibs if we got a resize event in the mean time.
135 ScopedVector<TransportDIB>::iterator it = 142 ScopedVector<TransportDIB>::iterator it =
136 std::find_if(dibs_.begin(), dibs_.end(), CompareById(id)); 143 std::find_if(dibs_.begin(), dibs_.end(), CompareById(id));
137 if (it != dibs_.end()) { 144 if (it != dibs_.end()) {
138 ++num_free_buffers_; 145 ++num_free_buffers_;
146 DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
147 return;
139 } else { 148 } else {
140 it = std::find_if(awaiting_ack_.begin(), 149 it = std::find_if(awaiting_ack_.begin(), awaiting_ack_.end(),
141 awaiting_ack_.end(),
142 CompareById(id)); 150 CompareById(id));
151 DCHECK(it != awaiting_ack_.end());
143 awaiting_ack_.erase(it); 152 awaiting_ack_.erase(it);
144 } 153 }
145
146 DCHECK_LE(static_cast<size_t>(num_free_buffers_), dibs_.size());
147 } 154 }
148 155
149 } // namespace content 156 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/gpu/compositor_software_output_device.h ('k') | content/renderer/render_widget.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698