Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/compositor/buffered_output_surface.h" | |
| 6 | |
| 7 #include "content/common/gpu/client/context_provider_command_buffer.h" | |
| 8 #include "gpu/GLES2/gl2extchromium.h" | |
| 9 #include "gpu/command_buffer/client/gles2_interface.h" | |
| 10 | |
| 11 namespace content { | |
| 12 | |
| 13 BufferedOutputSurface::BufferedOutputSurface( | |
| 14 scoped_refptr<cc::ContextProvider> context_provider, | |
| 15 unsigned int internalformat) | |
| 16 : context_provider_(context_provider), | |
| 17 fbo_(0), | |
| 18 depth_rb_(0), | |
| 19 tex_id_(0), | |
| 20 internalformat_(internalformat), | |
| 21 current_surface_(0), | |
| 22 last_surface_(0), | |
| 23 in_flight_surface_(0) { | |
| 24 Initialize(); | |
| 25 } | |
| 26 | |
| 27 BufferedOutputSurface::~BufferedOutputSurface() { | |
| 28 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
| 29 if (fbo_) | |
| 30 gl->DeleteFramebuffers(1, &fbo_); | |
| 31 if (depth_rb_) | |
| 32 gl->DeleteRenderbuffers(1, &depth_rb_); | |
| 33 if (tex_id_) | |
| 34 gl->DeleteTextures(1, &tex_id_); | |
| 35 FreeAllSurfaces(); | |
| 36 } | |
| 37 | |
| 38 void BufferedOutputSurface::Initialize() { | |
| 39 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
| 40 gl->GenFramebuffers(1, &fbo_); | |
| 41 gl->GenRenderbuffers(1, &depth_rb_); | |
| 42 gl->GenTextures(1, &tex_id_); | |
| 43 DCHECK(fbo_); | |
| 44 DCHECK(depth_rb_); | |
| 45 DCHECK(tex_id_); | |
| 46 } | |
| 47 | |
| 48 void BufferedOutputSurface::BindFramebuffer() { | |
| 49 if (!current_surface_) | |
| 50 current_surface_ = GetNextSurface(); | |
| 51 | |
| 52 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
| 53 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
| 54 gl->BindTexture(GL_TEXTURE_2D, tex_id_); | |
| 55 gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, current_surface_); | |
| 56 gl->FramebufferTexture2D( | |
| 57 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id_, 0); | |
| 58 } | |
| 59 | |
| 60 void BufferedOutputSurface::SwapBuffers() { | |
| 61 if (last_surface_) { | |
| 62 if (in_flight_surface_) | |
| 63 context_provider_->ContextGL()->DestroyImageCHROMIUM(in_flight_surface_); | |
| 64 else | |
| 65 in_flight_surface_ = last_surface_; | |
| 66 } | |
| 67 last_surface_ = current_surface_; | |
| 68 current_surface_ = 0; | |
| 69 } | |
| 70 | |
| 71 void BufferedOutputSurface::Reshape(const gfx::Size& size, float scale_factor) { | |
| 72 if (size == size_) | |
| 73 return; | |
| 74 size_ = size; | |
| 75 FreeAllSurfaces(); | |
| 76 | |
| 77 if (size_.width() == 0 || size_.height() == 0) | |
| 78 return; // Nothing to do. | |
| 79 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
| 80 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
| 81 gl->BindRenderbuffer(GL_RENDERBUFFER, depth_rb_); | |
| 82 gl->RenderbufferStorage( | |
| 83 GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, size_.width(), size_.height()); | |
| 84 gl->FramebufferRenderbuffer( | |
| 85 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb_); | |
| 86 } | |
| 87 | |
| 88 void BufferedOutputSurface::PageFlipComplete() { | |
| 89 if (in_flight_surface_) { | |
| 90 if (available_surfaces_.size() < 2) | |
|
alexst (slow to review)
2014/09/10 15:39:07
Let's not try to limit things to 2 buffers here, w
achaulk
2014/09/10 16:47:55
Actually thinking about it the check is redundant
| |
| 91 available_surfaces_.push_back(in_flight_surface_); | |
| 92 else | |
| 93 context_provider_->ContextGL()->DestroyImageCHROMIUM(in_flight_surface_); | |
| 94 } | |
| 95 in_flight_surface_ = 0; | |
| 96 } | |
| 97 | |
| 98 void BufferedOutputSurface::FreeAllSurfaces() { | |
| 99 FreeSurface(&in_flight_surface_); | |
| 100 FreeSurface(&last_surface_); | |
| 101 FreeSurface(¤t_surface_); | |
| 102 for (size_t i = 0; i < available_surfaces_.size(); i++) | |
| 103 context_provider_->ContextGL()->DestroyImageCHROMIUM( | |
|
alexst (slow to review)
2014/09/10 15:39:07
You are calling FreeSurface above, but Destroy dir
achaulk
2014/09/10 16:47:54
The free function is just a shortcut for release-a
| |
| 104 available_surfaces_[i]); | |
| 105 available_surfaces_.clear(); | |
| 106 } | |
| 107 | |
| 108 void BufferedOutputSurface::FreeSurface(unsigned int* surface) { | |
| 109 if (*surface) { | |
| 110 context_provider_->ContextGL()->DestroyImageCHROMIUM(*surface); | |
| 111 *surface = 0; | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 unsigned int BufferedOutputSurface::GetNextSurface() { | |
| 116 if (!available_surfaces_.empty()) { | |
| 117 unsigned int id = available_surfaces_.back(); | |
| 118 available_surfaces_.pop_back(); | |
| 119 return id; | |
| 120 } | |
| 121 | |
| 122 unsigned int id = context_provider_->ContextGL()->CreateImageCHROMIUM( | |
|
alexst (slow to review)
2014/09/10 15:39:07
Maybe we can associate an image with a unique text
achaulk
2014/09/10 16:47:55
We could, but then we would just have more things
| |
| 123 size_.width(), | |
| 124 size_.height(), | |
| 125 internalformat_, | |
| 126 GL_IMAGE_SCANOUT_CHROMIUM); | |
| 127 DCHECK(id); | |
| 128 return id; | |
| 129 } | |
| 130 | |
| 131 } // namespace content | |
| OLD | NEW |