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 FreeAllSurfaces(); | |
29 | |
30 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
31 if (fbo_) | |
32 gl->DeleteFramebuffers(1, &fbo_); | |
33 if (depth_rb_) | |
34 gl->DeleteRenderbuffers(1, &depth_rb_); | |
35 if (tex_id_) | |
36 gl->DeleteTextures(1, &tex_id_); | |
37 } | |
38 | |
39 void BufferedOutputSurface::Initialize() { | |
40 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
41 gl->GenFramebuffers(1, &fbo_); | |
42 gl->GenRenderbuffers(1, &depth_rb_); | |
43 gl->GenTextures(1, &tex_id_); | |
44 DCHECK(fbo_); | |
45 DCHECK(depth_rb_); | |
46 DCHECK(tex_id_); | |
47 } | |
48 | |
49 void BufferedOutputSurface::BindFramebuffer() { | |
50 if (!current_surface_) | |
51 current_surface_ = GetNextSurface(); | |
52 | |
53 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
54 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
55 gl->BindTexture(GL_TEXTURE_2D, tex_id_); | |
56 gl->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, current_surface_); | |
alexst (slow to review)
2014/09/10 17:37:08
I looked at the implementation, and this has a non
achaulk
2014/09/10 18:56:07
Done.
| |
57 gl->FramebufferTexture2D( | |
58 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id_, 0); | |
59 } | |
60 | |
61 void BufferedOutputSurface::SwapBuffers() { | |
62 if (last_surface_) { | |
63 if (in_flight_surface_) { | |
alexst (slow to review)
2014/09/10 17:37:08
Let's move this to bind.
achaulk
2014/09/10 18:56:07
We can't. Multiply calling bind is probably allowe
| |
64 // This is a case where a frame has been issued (bind/swap), and a second | |
65 // frame has been issued before receiving the PageFlipComplete for the | |
66 // first frame. We are now quad-buffering. | |
67 DCHECK(false); | |
alexst (slow to review)
2014/09/10 17:37:08
LOG(FATAL) << why we crashed
| |
68 context_provider_->ContextGL()->DestroyImageCHROMIUM(in_flight_surface_); | |
69 } else { | |
70 in_flight_surface_ = last_surface_; | |
71 } | |
72 } | |
73 last_surface_ = current_surface_; | |
74 current_surface_ = 0; | |
75 } | |
76 | |
77 void BufferedOutputSurface::Reshape(const gfx::Size& size, float scale_factor) { | |
78 if (size == size_) | |
79 return; | |
80 size_ = size; | |
81 FreeAllSurfaces(); | |
82 | |
83 if (size_.width() == 0 || size_.height() == 0) | |
84 return; // Nothing to do. | |
85 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
86 gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
87 gl->BindRenderbuffer(GL_RENDERBUFFER, depth_rb_); | |
88 gl->RenderbufferStorage( | |
89 GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, size_.width(), size_.height()); | |
90 gl->FramebufferRenderbuffer( | |
91 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb_); | |
92 } | |
93 | |
94 void BufferedOutputSurface::PageFlipComplete() { | |
95 if (in_flight_surface_) { | |
96 available_surfaces_.push_back(in_flight_surface_); | |
97 in_flight_surface_ = 0; | |
98 } | |
99 } | |
100 | |
101 void BufferedOutputSurface::FreeAllSurfaces() { | |
102 unsigned int bound_surface = | |
103 current_surface_ ? current_surface_ : last_surface_; | |
104 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | |
105 if (bound_surface) { | |
106 gl->BindTexture(GL_TEXTURE_2D, tex_id_); | |
107 gl->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, bound_surface); | |
108 } | |
109 FreeSurface(&in_flight_surface_); | |
110 FreeSurface(&last_surface_); | |
111 FreeSurface(¤t_surface_); | |
112 for (size_t i = 0; i < available_surfaces_.size(); i++) | |
113 gl->DestroyImageCHROMIUM(available_surfaces_[i]); | |
114 available_surfaces_.clear(); | |
115 } | |
116 | |
117 void BufferedOutputSurface::FreeSurface(unsigned int* surface) { | |
118 if (*surface) { | |
119 context_provider_->ContextGL()->DestroyImageCHROMIUM(*surface); | |
120 *surface = 0; | |
121 } | |
122 } | |
123 | |
124 unsigned int BufferedOutputSurface::GetNextSurface() { | |
125 if (!available_surfaces_.empty()) { | |
126 unsigned int id = available_surfaces_.back(); | |
127 available_surfaces_.pop_back(); | |
128 return id; | |
129 } | |
130 | |
131 unsigned int id = context_provider_->ContextGL()->CreateImageCHROMIUM( | |
132 size_.width(), | |
133 size_.height(), | |
134 internalformat_, | |
135 GL_IMAGE_SCANOUT_CHROMIUM); | |
136 DCHECK(id); | |
137 return id; | |
138 } | |
139 | |
140 } // namespace content | |
OLD | NEW |