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

Side by Side Diff: content/common/gpu/texture_image_transport_surface.cc

Issue 11194042: Implement TextureImageTransportSurface using texture mailbox (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 1 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 2 // found in the LICENSE file.
4 3
5 #include "content/common/gpu/texture_image_transport_surface.h" 4 #include "content/common/gpu/texture_image_transport_surface.h"
6 5
7 #include <string> 6 #include <string>
8 #include <vector> 7 #include <vector>
9 8
10 #include "base/command_line.h" 9 #include "base/command_line.h"
11 #include "content/common/gpu/gl_scoped_binders.h" 10 #include "content/common/gpu/gl_scoped_binders.h"
12 #include "content/common/gpu/gpu_channel.h" 11 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/gpu_channel_manager.h" 12 #include "content/common/gpu/gpu_channel_manager.h"
14 #include "content/common/gpu/gpu_messages.h" 13 #include "content/common/gpu/gpu_messages.h"
15 #include "content/common/gpu/sync_point_manager.h" 14 #include "content/common/gpu/sync_point_manager.h"
16 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
17 #include "gpu/command_buffer/service/context_group.h" 16 #include "gpu/command_buffer/service/context_group.h"
18 #include "gpu/command_buffer/service/gpu_scheduler.h" 17 #include "gpu/command_buffer/service/gpu_scheduler.h"
19 #include "gpu/command_buffer/service/texture_manager.h" 18 #include "gpu/command_buffer/service/texture_definition.h"
20 19
21 using gpu::gles2::ContextGroup; 20 using gpu::gles2::ContextGroup;
21 using gpu::gles2::MailboxManager;
22 using gpu::gles2::MailboxName;
23 using gpu::gles2::TextureDefinition;
22 using gpu::gles2::TextureManager; 24 using gpu::gles2::TextureManager;
23 typedef TextureManager::TextureInfo TextureInfo;
24 25
25 namespace content { 26 namespace content {
26 27
27 TextureImageTransportSurface::Texture::Texture() 28 TextureImageTransportSurface::Texture::Texture()
28 : client_id(0), 29 : service_id(0) {
29 sent_to_client(false) {
30 } 30 }
31 31
32 TextureImageTransportSurface::Texture::~Texture() { 32 TextureImageTransportSurface::Texture::~Texture() {
33 } 33 }
34 34
35 TextureImageTransportSurface::TextureImageTransportSurface( 35 TextureImageTransportSurface::TextureImageTransportSurface(
36 GpuChannelManager* manager, 36 GpuChannelManager* manager,
37 GpuCommandBufferStub* stub, 37 GpuCommandBufferStub* stub,
38 const gfx::GLSurfaceHandle& handle) 38 const gfx::GLSurfaceHandle& handle)
39 : fbo_id_(0), 39 : fbo_id_(0),
40 front_(0),
41 stub_destroyed_(false), 40 stub_destroyed_(false),
42 backbuffer_suggested_allocation_(true), 41 backbuffer_suggested_allocation_(true),
43 frontbuffer_suggested_allocation_(true), 42 frontbuffer_suggested_allocation_(true),
44 frontbuffer_is_protected_(true),
45 protection_state_id_(0),
46 handle_(handle), 43 handle_(handle),
47 parent_stub_(NULL),
48 is_swap_buffers_pending_(false), 44 is_swap_buffers_pending_(false),
49 did_unschedule_(false) { 45 did_unschedule_(false) {
50 helper_.reset(new ImageTransportHelper(this, 46 helper_.reset(new ImageTransportHelper(this,
51 manager, 47 manager,
52 stub, 48 stub,
53 gfx::kNullPluginWindow)); 49 gfx::kNullPluginWindow));
54 } 50 }
55 51
56 TextureImageTransportSurface::~TextureImageTransportSurface() { 52 TextureImageTransportSurface::~TextureImageTransportSurface() {
57 DCHECK(stub_destroyed_); 53 DCHECK(stub_destroyed_);
54
55 if (is_swap_buffers_pending_) {
56 scoped_ptr<TextureDefinition> definition(mailbox_manager_->ConsumeTexture(
57 GL_TEXTURE_2D, mailbox_name_));
58 if (definition.get()) {
59 uint32 service_id = definition->ReleaseServiceId();
60 GpuChannelManager* manager = helper_->manager();
61 DCHECK(manager);
62 if (manager->MakeCurrent(surface_.get()))
63 glDeleteTextures(1, &service_id);
64 }
65 }
66
58 Destroy(); 67 Destroy();
59 } 68 }
60 69
61 bool TextureImageTransportSurface::Initialize() { 70 bool TextureImageTransportSurface::Initialize() {
71 mailbox_manager_ =
72 helper_->stub()->decoder()->GetContextGroup()->mailbox_manager();
73 mailbox_manager_->GenerateMailboxName(&mailbox_name_);
74
75 GpuHostMsg_AcceleratedSurfaceNew_Params params;
76 params.width = 0;
77 params.height = 0;
78 params.mailbox_name.resize(sizeof(mailbox_name_));
79 memcpy(params.mailbox_name.data(), &mailbox_name_, sizeof(mailbox_name_));
80 helper_->SendAcceleratedSurfaceNew(params);
81
62 GpuChannelManager* manager = helper_->manager(); 82 GpuChannelManager* manager = helper_->manager();
63 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
64 if (!parent_channel)
65 return false;
66
67 parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id);
68 if (!parent_stub_)
69 return false;
70
71 parent_stub_->AddDestructionObserver(this);
72 TextureManager* texture_manager =
73 parent_stub_->decoder()->GetContextGroup()->texture_manager();
74 DCHECK(texture_manager);
75
76 for (int i = 0; i < 2; ++i) {
77 Texture& texture = textures_[i];
78 texture.client_id = handle_.parent_texture_id[i];
79 texture.info = texture_manager->GetTextureInfo(texture.client_id);
80 if (!texture.info)
81 return false;
82
83 if (!texture.info->target())
84 texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D);
85 texture_manager->SetParameter(
86 texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
87 texture_manager->SetParameter(
88 texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
89 texture_manager->SetParameter(
90 texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
91 texture_manager->SetParameter(
92 texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
93 }
94
95 surface_ = manager->GetDefaultOffscreenSurface(); 83 surface_ = manager->GetDefaultOffscreenSurface();
96 if (!surface_.get()) 84 if (!surface_.get())
97 return false; 85 return false;
98 86
99 if (!helper_->Initialize()) 87 if (!helper_->Initialize())
100 return false; 88 return false;
101 89
102 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 90 // TODO: Move this somewhere else.
103 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) 91 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
104 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); 92 if (parent_channel) {
93 const CommandLine* command_line = CommandLine::ForCurrentProcess();
94 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
95 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount());
96 }
105 97
106 return true; 98 return true;
107 } 99 }
108 100
109 void TextureImageTransportSurface::Destroy() { 101 void TextureImageTransportSurface::Destroy() {
110 if (parent_stub_) {
111 parent_stub_->decoder()->MakeCurrent();
112 ReleaseParentStub();
113 }
114
115 if (surface_.get()) 102 if (surface_.get())
116 surface_ = NULL; 103 surface_ = NULL;
117 104
118 helper_->Destroy(); 105 helper_->Destroy();
119 } 106 }
120 107
121 bool TextureImageTransportSurface::DeferDraws() { 108 bool TextureImageTransportSurface::DeferDraws() {
122 // The command buffer hit a draw/clear command that could clobber the 109 // The command buffer hit a draw/clear command that could clobber the
123 // texture in use by the UI compositor. If a Swap is pending, abort 110 // texture in use by the UI compositor. If a Swap is pending, abort
124 // processing of the command by returning true and unschedule until the Swap 111 // processing of the command by returning true and unschedule until the Swap
(...skipping 19 matching lines...) Expand all
144 if (stub_destroyed_) { 131 if (stub_destroyed_) {
145 // Early-exit so that we don't recreate the fbo. We still want to return 132 // Early-exit so that we don't recreate the fbo. We still want to return
146 // true, so that the context is made current and the GLES2DecoderImpl can 133 // true, so that the context is made current and the GLES2DecoderImpl can
147 // release its own resources. 134 // release its own resources.
148 return true; 135 return true;
149 } 136 }
150 137
151 if (!fbo_id_) { 138 if (!fbo_id_) {
152 glGenFramebuffersEXT(1, &fbo_id_); 139 glGenFramebuffersEXT(1, &fbo_id_);
153 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_); 140 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
154 CreateBackTexture(gfx::Size(1, 1)); 141 current_size_ = gfx::Size(1, 1);
142 CreateBackTexture();
155 143
156 #ifndef NDEBUG 144 #ifndef NDEBUG
157 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 145 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
158 if (status != GL_FRAMEBUFFER_COMPLETE) { 146 if (status != GL_FRAMEBUFFER_COMPLETE) {
159 DLOG(ERROR) << "Framebuffer incomplete."; 147 DLOG(ERROR) << "Framebuffer incomplete.";
160 glDeleteFramebuffersEXT(1, &fbo_id_); 148 glDeleteFramebuffersEXT(1, &fbo_id_);
161 fbo_id_ = 0; 149 fbo_id_ = 0;
162 return false; 150 return false;
163 } 151 }
164 #endif 152 #endif
(...skipping 10 matching lines...) Expand all
175 163
176 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { 164 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
177 if (backbuffer_suggested_allocation_ == allocation) 165 if (backbuffer_suggested_allocation_ == allocation)
178 return; 166 return;
179 backbuffer_suggested_allocation_ = allocation; 167 backbuffer_suggested_allocation_ = allocation;
180 168
181 if (!helper_->MakeCurrent()) 169 if (!helper_->MakeCurrent())
182 return; 170 return;
183 171
184 if (backbuffer_suggested_allocation_) { 172 if (backbuffer_suggested_allocation_) {
185 DCHECK(!textures_[back()].info->service_id() || 173 DCHECK(!backbuffer_.service_id);
186 !textures_[back()].sent_to_client); 174 CreateBackTexture();
187 CreateBackTexture(textures_[back()].size);
188 } else { 175 } else {
189 ReleaseTexture(back()); 176 ReleaseBackBuffer();
190 } 177 }
191 } 178 }
192 179
193 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 180 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
194 if (frontbuffer_suggested_allocation_ == allocation) 181 if (frontbuffer_suggested_allocation_ == allocation)
195 return; 182 return;
196 frontbuffer_suggested_allocation_ = allocation; 183 frontbuffer_suggested_allocation_ = allocation;
197 AdjustFrontBufferAllocation(); 184 AdjustFrontBufferAllocation();
198 } 185 }
199 186
200 void TextureImageTransportSurface::AdjustFrontBufferAllocation() { 187 void TextureImageTransportSurface::AdjustFrontBufferAllocation() {
201 if (!helper_->MakeCurrent()) 188 if (!helper_->MakeCurrent())
202 return; 189 return;
203 190
204 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && 191 if (!frontbuffer_suggested_allocation_) {
205 textures_[front()].info->service_id()) { 192 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
206 ReleaseTexture(front()); 193 helper_->SendAcceleratedSurfaceRelease(params);
207 if (textures_[front()].sent_to_client) {
208 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
209 params.identifier = textures_[front()].client_id;
210 helper_->SendAcceleratedSurfaceRelease(params);
211 textures_[front()].sent_to_client = false;
212 }
213 } 194 }
214 } 195 }
215 196
216 void* TextureImageTransportSurface::GetShareHandle() { 197 void* TextureImageTransportSurface::GetShareHandle() {
217 return GetHandle(); 198 return GetHandle();
218 } 199 }
219 200
220 void* TextureImageTransportSurface::GetDisplay() { 201 void* TextureImageTransportSurface::GetDisplay() {
221 return surface_.get() ? surface_->GetDisplay() : NULL; 202 return surface_.get() ? surface_->GetDisplay() : NULL;
222 } 203 }
223 204
224 void* TextureImageTransportSurface::GetConfig() { 205 void* TextureImageTransportSurface::GetConfig() {
225 return surface_.get() ? surface_->GetConfig() : NULL; 206 return surface_.get() ? surface_->GetConfig() : NULL;
226 } 207 }
227 208
228 void TextureImageTransportSurface::OnResize(gfx::Size size) { 209 void TextureImageTransportSurface::OnResize(gfx::Size size) {
229 CreateBackTexture(size); 210 current_size_ = size;
211 CreateBackTexture();
230 } 212 }
231 213
232 void TextureImageTransportSurface::OnWillDestroyStub( 214 void TextureImageTransportSurface::OnWillDestroyStub(
233 GpuCommandBufferStub* stub) { 215 GpuCommandBufferStub* stub) {
234 if (stub == parent_stub_) { 216 DCHECK(stub == helper_->stub());
235 ReleaseParentStub(); 217 stub->RemoveDestructionObserver(this);
236 helper_->SetPreemptByCounter(NULL);
237 } else {
238 DCHECK(stub == helper_->stub());
239 stub->RemoveDestructionObserver(this);
240 218
241 // We are losing the stub owning us, this is our last chance to clean up the 219 // We are losing the stub owning us, this is our last chance to clean up the
242 // resources we allocated in the stub's context. 220 // resources we allocated in the stub's context.
243 if (fbo_id_) { 221 if (fbo_id_) {
244 glDeleteFramebuffersEXT(1, &fbo_id_); 222 glDeleteFramebuffersEXT(1, &fbo_id_);
245 CHECK_GL_ERROR(); 223 CHECK_GL_ERROR();
246 fbo_id_ = 0; 224 fbo_id_ = 0;
247 } 225 }
248 226
249 stub_destroyed_ = true; 227 stub_destroyed_ = true;
250 }
251 } 228 }
252 229
253 bool TextureImageTransportSurface::SwapBuffers() { 230 bool TextureImageTransportSurface::SwapBuffers() {
254 DCHECK(backbuffer_suggested_allocation_); 231 DCHECK(backbuffer_suggested_allocation_);
255 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) 232 if (!frontbuffer_suggested_allocation_)
256 return true; 233 return true;
257 if (!parent_stub_) {
258 LOG(ERROR) << "SwapBuffers failed because no parent stub.";
259 return false;
260 }
261 234
262 glFlush(); 235 glFlush();
263 front_ = back(); 236 previous_damage_rect_ = gfx::Rect(backbuffer_.size);
264 previous_damage_rect_ = gfx::Rect(textures_[front()].size); 237 ProduceTexture(backbuffer_);
265 238
266 DCHECK(textures_[front()].client_id != 0); 239 // Do not allow destruction while we are still waiting for a swap ACK.
240 AddRef();
267 241
268 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 242 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
269 params.surface_handle = textures_[front()].client_id;
270 params.protection_state_id = protection_state_id_;
271 params.skip_ack = false;
272 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 243 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
273 244
274 DCHECK(!is_swap_buffers_pending_); 245 DCHECK(!is_swap_buffers_pending_);
275 is_swap_buffers_pending_ = true; 246 is_swap_buffers_pending_ = true;
276 return true; 247 return true;
277 } 248 }
278 249
279 bool TextureImageTransportSurface::PostSubBuffer( 250 bool TextureImageTransportSurface::PostSubBuffer(
280 int x, int y, int width, int height) { 251 int x, int y, int width, int height) {
281 DCHECK(backbuffer_suggested_allocation_); 252 DCHECK(backbuffer_suggested_allocation_);
282 DCHECK(textures_[back()].info->service_id()); 253 DCHECK(backbuffer_.service_id);
283 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) 254 if (!frontbuffer_suggested_allocation_)
284 return true; 255 return true;
285 // If we are recreating the frontbuffer with this swap, make sure we are
286 // drawing a full frame.
287 DCHECK(textures_[front()].info->service_id() ||
288 (!x && !y && gfx::Size(width, height) == textures_[back()].size));
289 if (!parent_stub_) {
290 LOG(ERROR) << "PostSubBuffer failed because no parent stub.";
291 return false;
292 }
293
294 const gfx::Rect new_damage_rect(x, y, width, height); 256 const gfx::Rect new_damage_rect(x, y, width, height);
295 257
296 // An empty damage rect is a successful no-op. 258 // An empty damage rect is a successful no-op.
297 if (new_damage_rect.IsEmpty()) 259 if (new_damage_rect.IsEmpty())
298 return true; 260 return true;
299 261
300 int back_texture_service_id = textures_[back()].info->service_id(); 262 glFlush();
301 int front_texture_service_id = textures_[front()].info->service_id(); 263 previous_damage_rect_ = new_damage_rect;
264 ProduceTexture(backbuffer_);
302 265
303 gfx::Size expected_size = textures_[back()].size; 266 // Do not allow destruction while we are still waiting for a swap ACK.
304 bool surfaces_same_size = textures_[front()].size == expected_size; 267 AddRef();
305
306 if (surfaces_same_size) {
307 std::vector<gfx::Rect> regions_to_copy;
308 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, &regions_to_copy);
309
310 ScopedFrameBufferBinder fbo_binder(fbo_id_);
311 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
312 GL_COLOR_ATTACHMENT0,
313 GL_TEXTURE_2D,
314 front_texture_service_id,
315 0);
316 ScopedTextureBinder texture_binder(back_texture_service_id);
317
318 for (size_t i = 0; i < regions_to_copy.size(); ++i) {
319 const gfx::Rect& region_to_copy = regions_to_copy[i];
320 if (!region_to_copy.IsEmpty()) {
321 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, region_to_copy.x(),
322 region_to_copy.y(), region_to_copy.x(), region_to_copy.y(),
323 region_to_copy.width(), region_to_copy.height());
324 }
325 }
326 } else {
327 DCHECK(new_damage_rect == gfx::Rect(expected_size));
328 }
329
330 glFlush();
331 front_ = back();
332 previous_damage_rect_ = new_damage_rect;
333
334 DCHECK(textures_[front()].client_id);
335 268
336 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 269 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
337 params.surface_handle = textures_[front()].client_id;
338 params.x = x; 270 params.x = x;
339 params.y = y; 271 params.y = y;
340 params.width = width; 272 params.width = width;
341 params.height = height; 273 params.height = height;
342 params.protection_state_id = protection_state_id_;
343 helper_->SendAcceleratedSurfacePostSubBuffer(params); 274 helper_->SendAcceleratedSurfacePostSubBuffer(params);
344 275
345 DCHECK(!is_swap_buffers_pending_); 276 DCHECK(!is_swap_buffers_pending_);
346 is_swap_buffers_pending_ = true; 277 is_swap_buffers_pending_ = true;
347 return true; 278 return true;
348 } 279 }
349 280
350 std::string TextureImageTransportSurface::GetExtensions() { 281 std::string TextureImageTransportSurface::GetExtensions() {
351 std::string extensions = gfx::GLSurface::GetExtensions(); 282 std::string extensions = gfx::GLSurface::GetExtensions();
352 extensions += extensions.empty() ? "" : " "; 283 extensions += extensions.empty() ? "" : " ";
353 extensions += "GL_CHROMIUM_front_buffer_cached "; 284 extensions += "GL_CHROMIUM_front_buffer_cached ";
354 extensions += "GL_CHROMIUM_post_sub_buffer"; 285 extensions += "GL_CHROMIUM_post_sub_buffer";
355 return extensions; 286 return extensions;
356 } 287 }
357 288
358 gfx::Size TextureImageTransportSurface::GetSize() { 289 gfx::Size TextureImageTransportSurface::GetSize() {
359 gfx::Size size = textures_[back()].size; 290 gfx::Size size = current_size_;
360 291
361 // OSMesa expects a non-zero size. 292 // OSMesa expects a non-zero size.
362 return gfx::Size(size.width() == 0 ? 1 : size.width(), 293 return gfx::Size(size.width() == 0 ? 1 : size.width(),
363 size.height() == 0 ? 1 : size.height()); 294 size.height() == 0 ? 1 : size.height());
364 } 295 }
365 296
366 void* TextureImageTransportSurface::GetHandle() { 297 void* TextureImageTransportSurface::GetHandle() {
367 return surface_.get() ? surface_->GetHandle() : NULL; 298 return surface_.get() ? surface_->GetHandle() : NULL;
368 } 299 }
369 300
370 unsigned TextureImageTransportSurface::GetFormat() { 301 unsigned TextureImageTransportSurface::GetFormat() {
371 return surface_.get() ? surface_->GetFormat() : 0; 302 return surface_.get() ? surface_->GetFormat() : 0;
372 } 303 }
373 304
374 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
375 bool is_protected, uint32 protection_state_id) {
376 protection_state_id_ = protection_state_id;
377 if (frontbuffer_is_protected_ == is_protected)
378 return;
379 frontbuffer_is_protected_ = is_protected;
380 AdjustFrontBufferAllocation();
381
382 // If surface is set to protected, and we haven't actually released it yet,
383 // we can set the ui surface handle now just by sending a swap message.
384 if (is_protected && textures_[front()].info->service_id() &&
385 textures_[front()].sent_to_client) {
386 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
387 params.surface_handle = textures_[front()].client_id;
388 params.protection_state_id = protection_state_id_;
389 params.skip_ack = true;
390 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
391 }
392 }
393
394 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) { 305 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) {
395 if (sync_point == 0) { 306 if (sync_point == 0) {
396 BufferPresentedImpl(); 307 BufferPresentedImpl();
397 } else { 308 } else {
398 helper_->manager()->sync_point_manager()->AddSyncPointCallback( 309 helper_->manager()->sync_point_manager()->AddSyncPointCallback(
399 sync_point, 310 sync_point,
400 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, 311 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, this));
401 this->AsWeakPtr()));
402 } 312 }
313
314 // Careful, we might get deleted now if we were only waiting for
315 // a final swap ACK.
316 Release();
403 } 317 }
404 318
405 void TextureImageTransportSurface::BufferPresentedImpl() { 319 void TextureImageTransportSurface::BufferPresentedImpl() {
320 if (stub_destroyed_)
321 return;
322
406 DCHECK(is_swap_buffers_pending_); 323 DCHECK(is_swap_buffers_pending_);
407 is_swap_buffers_pending_ = false; 324 is_swap_buffers_pending_ = false;
408 325
409 // We're relying on the fact that the parent context is 326 // We're relying on the fact that the parent context is
410 // finished with it's context when it inserts the sync point that 327 // finished with it's context when it inserts the sync point that
411 // triggers this callback. 328 // triggers this callback.
412 if (helper_->MakeCurrent()) { 329 if (helper_->MakeCurrent()) {
413 if (textures_[front()].size != textures_[back()].size || 330 DCHECK(!backbuffer_.service_id);
414 !textures_[back()].info->service_id() || 331 ConsumeTexture(backbuffer_);
415 !textures_[back()].sent_to_client) { 332 if (backbuffer_.size != current_size_ ||
333 !backbuffer_.service_id) {
416 // We may get an ACK from a stale swap just to reschedule. In that case, 334 // We may get an ACK from a stale swap just to reschedule. In that case,
417 // we may not have a backbuffer suggestion and should not recreate one. 335 // we may not have a backbuffer suggestion and should not recreate one.
418 if (backbuffer_suggested_allocation_) 336 if (backbuffer_suggested_allocation_)
419 CreateBackTexture(textures_[front()].size); 337 CreateBackTexture();
420 } else { 338 } else {
421 AttachBackTextureToFBO(); 339 AttachBackTextureToFBO();
422 } 340 }
423 } 341 }
424 342
425 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context 343 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
426 // logic. 344 // logic.
427 if (did_unschedule_) { 345 if (did_unschedule_) {
428 did_unschedule_ = false; 346 did_unschedule_ = false;
429 helper_->SetScheduled(true); 347 helper_->SetScheduled(true);
430 } 348 }
431 } 349 }
432 350
433 void TextureImageTransportSurface::OnResizeViewACK() { 351 void TextureImageTransportSurface::OnResizeViewACK() {
434 NOTREACHED(); 352 NOTREACHED();
435 } 353 }
436 354
437 void TextureImageTransportSurface::ReleaseTexture(int id) { 355 void TextureImageTransportSurface::ReleaseBackBuffer() {
438 if (!parent_stub_) 356 if (!backbuffer_.service_id)
439 return; 357 return;
440 Texture& texture = textures_[id];
441 TextureInfo* info = texture.info;
442 DCHECK(info);
443
444 GLuint service_id = info->service_id();
445 if (!service_id)
446 return;
447 info->SetServiceId(0);
448 358
449 { 359 {
450 ScopedFrameBufferBinder fbo_binder(fbo_id_); 360 ScopedFrameBufferBinder fbo_binder(fbo_id_);
451 glDeleteTextures(1, &service_id); 361 glDeleteTextures(1, &backbuffer_.service_id);
362 backbuffer_.service_id = 0;
452 } 363 }
453 glFlush(); 364 glFlush();
454 CHECK_GL_ERROR(); 365 CHECK_GL_ERROR();
455 } 366 }
456 367
457 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { 368 void TextureImageTransportSurface::CreateBackTexture() {
458 if (!parent_stub_) 369 // We are waiting for our backbuffer in the mailbox, so we shouldn't be
459 return; 370 // reallocating the backbuffer now.
460 Texture& texture = textures_[back()]; 371 DCHECK(!is_swap_buffers_pending_);
461 TextureInfo* info = texture.info;
462 DCHECK(info);
463 372
464 GLuint service_id = info->service_id(); 373 gfx::Size& size = current_size_;
374 Texture& texture = backbuffer_;
465 375
466 if (service_id && texture.size == size && texture.sent_to_client) 376 if (texture.service_id && texture.size == size)
467 return; 377 return;
468 378
469 if (!service_id) { 379 if (!texture.service_id) {
470 glGenTextures(1, &service_id); 380 glGenTextures(1, &texture.service_id);
471 info->SetServiceId(service_id);
472 } 381 }
473 382
474 if (size != texture.size) { 383 if (size != texture.size) {
475 texture.size = size; 384 texture.size = size;
476 TextureManager* texture_manager =
477 parent_stub_->decoder()->GetContextGroup()->texture_manager();
478 texture_manager->SetLevelInfo(
479 info,
480 GL_TEXTURE_2D,
481 0,
482 GL_RGBA,
483 size.width(),
484 size.height(),
485 1,
486 0,
487 GL_RGBA,
488 GL_UNSIGNED_BYTE,
489 true);
490 } 385 }
491 386
492 { 387 {
493 ScopedTextureBinder texture_binder(service_id); 388 ScopedTextureBinder texture_binder(texture.service_id);
494 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 389 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
495 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 390 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
496 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
497 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
498 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 393 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
499 size.width(), size.height(), 0, 394 size.width(), size.height(), 0,
500 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 395 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
501 CHECK_GL_ERROR(); 396 CHECK_GL_ERROR();
502 } 397 }
503 398
504 AttachBackTextureToFBO(); 399 AttachBackTextureToFBO();
505
506 GpuHostMsg_AcceleratedSurfaceNew_Params params;
507 params.width = size.width();
508 params.height = size.height();
509 params.surface_handle = texture.client_id;
510 helper_->SendAcceleratedSurfaceNew(params);
511 texture.sent_to_client = true;
512 } 400 }
513 401
514 void TextureImageTransportSurface::AttachBackTextureToFBO() { 402 void TextureImageTransportSurface::AttachBackTextureToFBO() {
515 if (!parent_stub_) 403 DCHECK(backbuffer_.service_id);
516 return;
517 TextureInfo* info = textures_[back()].info;
518 DCHECK(info);
519
520 ScopedFrameBufferBinder fbo_binder(fbo_id_); 404 ScopedFrameBufferBinder fbo_binder(fbo_id_);
521 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 405 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
522 GL_COLOR_ATTACHMENT0, 406 GL_COLOR_ATTACHMENT0,
523 GL_TEXTURE_2D, 407 GL_TEXTURE_2D,
524 info->service_id(), 408 backbuffer_.service_id,
525 0); 409 0);
526 glFlush(); 410 glFlush();
527 CHECK_GL_ERROR(); 411 CHECK_GL_ERROR();
528 412
529 #ifndef NDEBUG 413 #ifndef NDEBUG
530 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 414 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
531 if (status != GL_FRAMEBUFFER_COMPLETE) { 415 if (status != GL_FRAMEBUFFER_COMPLETE) {
532 DLOG(ERROR) << "Framebuffer incomplete."; 416 DLOG(ERROR) << "Framebuffer incomplete: " << status;
417 DCHECK(false);
533 } 418 }
534 #endif 419 #endif
535 } 420 }
536 421
537 void TextureImageTransportSurface::ReleaseParentStub() { 422 void TextureImageTransportSurface::ConsumeTexture(Texture& texture) {
538 DCHECK(parent_stub_); 423 DCHECK(!texture.service_id);
539 parent_stub_->RemoveDestructionObserver(this); 424 scoped_ptr<TextureDefinition> definition(mailbox_manager_->ConsumeTexture(
540 for (int i = 0; i < 2; ++i) { 425 GL_TEXTURE_2D, mailbox_name_));
541 Texture& texture = textures_[i]; 426 if (definition.get()) {
542 texture.info = NULL; 427 texture.service_id = definition->ReleaseServiceId();
543 if (!texture.sent_to_client) 428 texture.size = gfx::Size(definition->level_infos()[0][0].width,
544 continue; 429 definition->level_infos()[0][0].height);
545 GpuHostMsg_AcceleratedSurfaceRelease_Params params;
546 params.identifier = texture.client_id;
547 helper_->SendAcceleratedSurfaceRelease(params);
548 } 430 }
549 parent_stub_ = NULL; 431 }
432
433 void TextureImageTransportSurface::ProduceTexture(Texture& texture) {
434 DCHECK(texture.service_id);
435 TextureManager* texture_manager =
436 helper_->stub()->decoder()->GetContextGroup()->texture_manager();
437 DCHECK(texture.size.width() > 0 && texture.size.height() > 0);
438 TextureDefinition::LevelInfo info(
439 GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1,
440 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
441
442 TextureDefinition::LevelInfos level_infos;
443 level_infos.resize(1);
444 level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D));
445 level_infos[0][0] = info;
446 scoped_ptr<TextureDefinition> definition(new TextureDefinition(
447 GL_TEXTURE_2D,
448 texture.service_id,
449 true,
450 level_infos));
451 mailbox_manager_->ProduceTexture(
452 GL_TEXTURE_2D,
453 mailbox_name_,
454 definition.release(),
455 helper_->stub()->decoder()->GetContextGroup()->texture_manager());
456 texture.service_id = 0;
550 } 457 }
551 458
552 } // namespace content 459 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698