OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/gpu/mailbox_output_surface.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "cc/compositor_frame.h" | |
9 #include "cc/compositor_frame_ack.h" | |
10 #include "cc/gl_frame_data.h" | |
11 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h" | |
12 #include "third_party/khronos/GLES2/gl2.h" | |
13 #include "third_party/khronos/GLES2/gl2ext.h" | |
14 | |
15 using cc::CompositorFrame; | |
16 using cc::GLFrameData; | |
17 using cc::Mailbox; | |
18 using WebKit::WebGraphicsContext3D; | |
19 | |
20 namespace content { | |
21 | |
22 MailboxOutputSurface::MailboxOutputSurface( | |
23 int32 routing_id, | |
24 WebGraphicsContext3D* context3D, | |
25 cc::SoftwareOutputDevice* software_device) | |
26 : CompositorOutputSurface(routing_id, | |
27 context3D, | |
28 software_device), | |
29 fbo_(0) { | |
30 } | |
31 | |
32 MailboxOutputSurface::~MailboxOutputSurface() { | |
33 DiscardBackbuffer(); | |
34 } | |
35 | |
36 void MailboxOutputSurface::EnsureBackbuffer() { | |
37 if (!current_backing_.texture_id) { | |
38 // Find a texture of matching size to recycle. | |
39 while (returned_textures_.size()) { | |
piman
2013/02/27 23:51:04
!returned_textures_.empty()
no sievers
2013/02/28 18:43:40
Done.
| |
40 TransferableFrame& texture = returned_textures_.front(); | |
41 if (texture.size == size_) { | |
42 current_backing_ = texture; | |
43 returned_textures_.pop(); | |
44 break; | |
45 } | |
46 | |
47 context3d_->deleteTexture(texture.texture_id); | |
48 returned_textures_.pop(); | |
49 } | |
50 | |
51 if (!current_backing_.texture_id) { | |
52 current_backing_.texture_id = context3d_->createTexture(); | |
53 current_backing_.size = size_; | |
54 context3d_->genMailboxCHROMIUM(current_backing_.mailbox.name); | |
55 context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id); | |
56 context3d_->texParameteri( | |
57 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
58 context3d_->texParameteri( | |
59 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
60 context3d_->texParameteri( | |
61 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
62 context3d_->texParameteri( | |
63 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
64 context3d_->texImage2D( | |
65 GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0, | |
66 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
67 } | |
68 } | |
69 } | |
70 | |
71 void MailboxOutputSurface::DiscardBackbuffer() { | |
72 if (current_backing_.texture_id) { | |
73 context3d_->deleteTexture(current_backing_.texture_id); | |
74 current_backing_ = TransferableFrame(); | |
75 } | |
76 | |
77 while (returned_textures_.size()) { | |
piman
2013/02/27 23:51:04
!returned_textures_.empty()
no sievers
2013/02/28 18:43:40
Done.
| |
78 context3d_->deleteTexture(returned_textures_.front().texture_id); | |
79 returned_textures_.pop(); | |
80 } | |
81 | |
82 if (fbo_) { | |
83 context3d_->bindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
84 context3d_->deleteFramebuffer(fbo_); | |
85 fbo_ = 0; | |
86 } | |
87 } | |
88 | |
89 void MailboxOutputSurface::Reshape(const gfx::Size& size) { | |
90 size_ = size; | |
Sami
2013/02/28 12:46:58
Should we DCHECK here that size_ != size? Hopefull
no sievers
2013/02/28 18:43:40
I added an early-return.
| |
91 DiscardBackbuffer(); | |
92 EnsureBackbuffer(); | |
93 } | |
94 | |
95 void MailboxOutputSurface::BindFramebuffer() { | |
96 EnsureBackbuffer(); | |
97 DCHECK(current_backing_.texture_id); | |
98 | |
99 if (!fbo_) | |
100 fbo_ = context3d_->createFramebuffer(); | |
Sami
2013/02/28 12:46:58
Nit: indent by 2.
no sievers
2013/02/28 18:43:40
Done.
| |
101 context3d_->bindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
102 context3d_->framebufferTexture2D( | |
103 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | |
104 current_backing_.texture_id, 0); | |
105 } | |
106 | |
107 void MailboxOutputSurface::SendFrameToParentCompositor( | |
108 cc::CompositorFrame* frame) { | |
109 frame->gl_frame_data.reset(new GLFrameData()); | |
110 | |
111 DCHECK(!size_.IsEmpty()); | |
112 DCHECK(size_ == current_backing_.size); | |
113 DCHECK(!current_backing_.mailbox.isZero()); | |
114 | |
115 context3d_->framebufferTexture2D( | |
116 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); | |
117 context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id); | |
118 context3d_->produceTextureCHROMIUM( | |
119 GL_TEXTURE_2D, current_backing_.mailbox.name); | |
120 frame->gl_frame_data->mailbox = current_backing_.mailbox; | |
121 frame->gl_frame_data->size = current_backing_.size; | |
122 context3d_->flush(); | |
123 frame->gl_frame_data->sync_point = context3d_->insertSyncPoint(); | |
124 context3d_->deleteTexture(current_backing_.texture_id); | |
piman
2013/02/27 23:51:04
note: for a follow-up probably, but you may want t
no sievers
2013/02/28 18:43:40
TODO added.
| |
125 current_backing_ = TransferableFrame(); | |
126 CompositorOutputSurface::SendFrameToParentCompositor(frame); | |
piman
2013/02/27 23:51:04
nit: can you move this above the deleteTexture? It
no sievers
2013/02/28 18:43:40
Done.
| |
127 } | |
128 | |
129 void MailboxOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) { | |
130 if (!ack.gl_frame_data->mailbox.isZero()) { | |
131 DCHECK(!ack.gl_frame_data->size.IsEmpty()); | |
132 uint32 texture_id = context3d_->createTexture(); | |
133 TransferableFrame texture( | |
134 texture_id, ack.gl_frame_data->mailbox, ack.gl_frame_data->size); | |
135 | |
136 context3d_->bindTexture(GL_TEXTURE_2D, texture_id); | |
137 | |
138 // If the consumer is bouncing back the same texture (i.e. skipping the | |
139 // frame), we don't have to synchronize here (sync_point == 0). | |
140 if (ack.gl_frame_data->sync_point) | |
141 context3d_->waitSyncPoint(ack.gl_frame_data->sync_point); | |
piman
2013/02/27 23:51:04
note: a potential optimization (for a follow-up to
no sievers
2013/02/28 18:43:40
TODO added.
| |
142 | |
143 context3d_->consumeTextureCHROMIUM( | |
144 GL_TEXTURE_2D, ack.gl_frame_data->mailbox.name); | |
145 returned_textures_.push(texture); | |
146 } | |
147 CompositorOutputSurface::OnSwapAck(ack); | |
148 } | |
149 | |
150 void MailboxOutputSurface::SwapBuffers() { | |
151 } | |
152 | |
153 void MailboxOutputSurface::PostSubBuffer(const gfx::Rect& rect) { | |
154 NOTIMPLEMENTED() | |
155 << "Partial swap not supported with composite-to-mailbox yet."; | |
156 } | |
157 | |
158 } // namespace content | |
OLD | NEW |