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 |