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

Side by Side Diff: content/browser/compositor/buffer_queue.cc

Issue 571623003: Partial swap implementation for surfaceless (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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 "content/browser/compositor/buffer_queue.h" 5 #include "content/browser/compositor/buffer_queue.h"
6 6
7 #include "content/common/gpu/client/context_provider_command_buffer.h" 7 #include "content/common/gpu/client/context_provider_command_buffer.h"
8 #include "content/common/gpu/client/gl_helper.h"
8 #include "gpu/GLES2/gl2extchromium.h" 9 #include "gpu/GLES2/gl2extchromium.h"
9 #include "gpu/command_buffer/client/gles2_interface.h" 10 #include "gpu/command_buffer/client/gles2_interface.h"
11 #include "third_party/skia/include/core/SkRect.h"
12 #include "third_party/skia/include/core/SkRegion.h"
10 13
11 namespace content { 14 namespace content {
12 15
13 BufferQueue::BufferQueue(scoped_refptr<cc::ContextProvider> context_provider, 16 BufferQueue::BufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
17 GLHelper* gl_helper,
14 unsigned int internalformat) 18 unsigned int internalformat)
15 : context_provider_(context_provider), 19 : context_provider_(context_provider),
16 fbo_(0), 20 fbo_(0),
17 allocated_count_(0), 21 allocated_count_(0),
18 internalformat_(internalformat) { 22 internalformat_(internalformat),
23 gl_helper_(gl_helper) {
19 } 24 }
20 25
21 BufferQueue::~BufferQueue() { 26 BufferQueue::~BufferQueue() {
22 FreeAllSurfaces(); 27 FreeAllSurfaces();
23 28
24 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 29 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
25 if (fbo_) 30 if (fbo_)
26 gl->DeleteFramebuffers(1, &fbo_); 31 gl->DeleteFramebuffers(1, &fbo_);
27 } 32 }
28 33
(...skipping 10 matching lines...) Expand all
39 if (!current_surface_.texture) { 44 if (!current_surface_.texture) {
40 current_surface_ = GetNextSurface(); 45 current_surface_ = GetNextSurface();
41 gl->FramebufferTexture2D(GL_FRAMEBUFFER, 46 gl->FramebufferTexture2D(GL_FRAMEBUFFER,
42 GL_COLOR_ATTACHMENT0, 47 GL_COLOR_ATTACHMENT0,
43 GL_TEXTURE_2D, 48 GL_TEXTURE_2D,
44 current_surface_.texture, 49 current_surface_.texture,
45 0); 50 0);
46 } 51 }
47 } 52 }
48 53
49 void BufferQueue::SwapBuffers() { 54 void BufferQueue::CopyBufferDamage(int texture,
50 in_flight_surfaces_.push(current_surface_); 55 int source_texture,
56 const gfx::Rect& exclude_rect,
57 const gfx::Rect& copy_rect) {
58 gl_helper_->CopySubBufferDamage(
59 texture,
60 source_texture,
61 SkRegion(SkIRect::MakeXYWH(exclude_rect.x(),
62 exclude_rect.y(),
63 exclude_rect.width(),
64 exclude_rect.height())),
65 SkRegion(SkIRect::MakeXYWH(copy_rect.x(),
66 copy_rect.y(),
67 copy_rect.width(),
68 copy_rect.height())));
69 }
70
71 void BufferQueue::SwapBuffers(const gfx::Rect& damage) {
72 if (damage != gfx::Rect(size_)) {
73 // We must have a frame available to copy from.
74 DCHECK(!in_flight_surfaces_.empty());
75
76 if (!damage.Contains(current_surface_.damage)) {
alexst (slow to review) 2014/09/18 15:39:15 Contract on CopyBufferDamage says "Copies all pixe
achaulk 2014/09/18 16:45:02 Sure, but we need it anyway for the below set
77 CopyBufferDamage(current_surface_.texture,
78 in_flight_surfaces_.back().texture,
79 damage,
80 current_surface_.damage);
81 // Because we copied everything except |damage| to this texture,
82 // the cumulative damage for this frame is only |damage| now.
83 in_flight_surfaces_.back().damage = damage;
alexst (slow to review) 2014/09/18 15:39:15 I think this is redundant with the for loop below
achaulk 2014/09/18 16:45:02 Not entirely, the important bit is that it any exi
84 }
85
86 // Compute cumulative damage for all frames.
87 for (size_t i = 0; i < available_surfaces_.size(); i++)
alexst (slow to review) 2014/09/18 15:39:15 Can you break this into a separate function SetDam
achaulk 2014/09/18 16:45:02 Sure
88 available_surfaces_[i].damage.Union(damage);
89 for (std::deque<AllocatedSurface>::iterator it =
90 in_flight_surfaces_.begin();
91 it != in_flight_surfaces_.end();
92 ++it)
93 it->damage.Union(damage);
94 } else {
95 for (size_t i = 0; i < available_surfaces_.size(); i++)
96 available_surfaces_[i].damage = damage;
97 for (std::deque<AllocatedSurface>::iterator it =
98 in_flight_surfaces_.begin();
99 it != in_flight_surfaces_.end();
100 ++it)
101 it->damage = damage;
102 }
103 current_surface_.damage = gfx::Rect();
104 in_flight_surfaces_.push_back(current_surface_);
51 current_surface_.texture = 0; 105 current_surface_.texture = 0;
52 current_surface_.image = 0; 106 current_surface_.image = 0;
53 } 107 }
54 108
55 void BufferQueue::Reshape(const gfx::Size& size, float scale_factor) { 109 void BufferQueue::Reshape(const gfx::Size& size, float scale_factor) {
56 DCHECK(!current_surface_.texture); 110 DCHECK(!current_surface_.texture);
57 if (size == size_) 111 if (size == size_)
58 return; 112 return;
59 size_ = size; 113 size_ = size;
60 114
61 // TODO: add stencil buffer when needed. 115 // TODO: add stencil buffer when needed.
62 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 116 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
63 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); 117 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
64 gl->FramebufferTexture2D( 118 gl->FramebufferTexture2D(
65 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 119 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
66 120
67 FreeAllSurfaces(); 121 FreeAllSurfaces();
68 } 122 }
69 123
70 void BufferQueue::PageFlipComplete() { 124 void BufferQueue::PageFlipComplete() {
71 if (in_flight_surfaces_.size() > 1) { 125 if (in_flight_surfaces_.size() > 1) {
72 available_surfaces_.push_back(in_flight_surfaces_.front()); 126 available_surfaces_.push_back(in_flight_surfaces_.front());
73 in_flight_surfaces_.pop(); 127 in_flight_surfaces_.pop_front();
74 } 128 }
75 } 129 }
76 130
77 void BufferQueue::FreeAllSurfaces() { 131 void BufferQueue::FreeAllSurfaces() {
78 FreeSurface(&current_surface_); 132 FreeSurface(&current_surface_);
79 while (!in_flight_surfaces_.empty()) { 133 while (!in_flight_surfaces_.empty()) {
80 FreeSurface(&in_flight_surfaces_.front()); 134 FreeSurface(&in_flight_surfaces_.front());
81 in_flight_surfaces_.pop(); 135 in_flight_surfaces_.pop_front();
82 } 136 }
83 for (size_t i = 0; i < available_surfaces_.size(); i++) 137 for (size_t i = 0; i < available_surfaces_.size(); i++)
84 FreeSurface(&available_surfaces_[i]); 138 FreeSurface(&available_surfaces_[i]);
85 available_surfaces_.clear(); 139 available_surfaces_.clear();
86 } 140 }
87 141
88 void BufferQueue::FreeSurface(AllocatedSurface* surface) { 142 void BufferQueue::FreeSurface(AllocatedSurface* surface) {
89 if (surface->texture) { 143 if (surface->texture) {
90 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 144 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
91 gl->BindTexture(GL_TEXTURE_2D, surface->texture); 145 gl->BindTexture(GL_TEXTURE_2D, surface->texture);
92 gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, surface->image); 146 gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, surface->image);
93 gl->DeleteTextures(1, &surface->texture); 147 gl->DeleteTextures(1, &surface->texture);
94 gl->DestroyImageCHROMIUM(surface->image); 148 gl->DestroyImageCHROMIUM(surface->image);
95 surface->image = 0; 149 surface->image = 0;
96 surface->texture = 0; 150 surface->texture = 0;
97 allocated_count_--; 151 allocated_count_--;
98 } 152 }
99 } 153 }
100 154
101 BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() { 155 BufferQueue::AllocatedSurface BufferQueue::GetNextSurface() {
102 if (!available_surfaces_.empty()) { 156 if (!available_surfaces_.empty()) {
103 AllocatedSurface id = available_surfaces_.back(); 157 AllocatedSurface surface = available_surfaces_.back();
104 available_surfaces_.pop_back(); 158 available_surfaces_.pop_back();
105 return id; 159 return surface;
106 } 160 }
107 161
108 unsigned int texture = 0; 162 unsigned int texture = 0;
109 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 163 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
110 gl->GenTextures(1, &texture); 164 gl->GenTextures(1, &texture);
111 if (!texture) 165 if (!texture)
112 return AllocatedSurface(); 166 return AllocatedSurface();
113 167
114 // We don't want to allow anything more than triple buffering. 168 // We don't want to allow anything more than triple buffering.
115 DCHECK_LT(allocated_count_, 4U); 169 DCHECK_LT(allocated_count_, 4U);
116 170
117 unsigned int id = context_provider_->ContextGL()->CreateImageCHROMIUM( 171 unsigned int id = context_provider_->ContextGL()->CreateImageCHROMIUM(
118 size_.width(), 172 size_.width(),
119 size_.height(), 173 size_.height(),
120 internalformat_, 174 internalformat_,
121 GL_IMAGE_SCANOUT_CHROMIUM); 175 GL_IMAGE_SCANOUT_CHROMIUM);
122 allocated_count_++; 176 allocated_count_++;
123 gl->BindTexture(GL_TEXTURE_2D, texture); 177 gl->BindTexture(GL_TEXTURE_2D, texture);
124 gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, id); 178 gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, id);
125 return AllocatedSurface(texture, id); 179 return AllocatedSurface(texture, id, gfx::Rect(size_));
126 } 180 }
127 181
128 } // namespace content 182 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698