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 if (fbo_) | |
34 context3d_->deleteFramebuffer(fbo_); | |
35 | |
36 DiscardBackbuffer(); | |
37 } | |
38 | |
39 void MailboxOutputSurface::EnsureBackbuffer() { | |
40 if (!current_backing_.texture_id) { | |
41 // Find a texture of matching size to recycle. | |
42 while (returned_textures_.size()) { | |
43 TransferableFrame& texture = returned_textures_.front(); | |
44 if (texture.size == size_) { | |
45 current_backing_ = texture; | |
46 returned_textures_.pop(); | |
47 break; | |
48 } | |
49 | |
50 context3d_->deleteTexture(texture.texture_id); | |
51 returned_textures_.pop(); | |
52 } | |
53 | |
54 if (!current_backing_.texture_id) { | |
55 current_backing_.texture_id = context3d_->createTexture(); | |
56 current_backing_.size = size_; | |
57 context3d_->genMailboxCHROMIUM(current_backing_.mailbox.name); | |
58 context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id); | |
59 context3d_->texParameteri( | |
60 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
61 context3d_->texParameteri( | |
62 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
63 context3d_->texParameteri( | |
64 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
65 context3d_->texParameteri( | |
66 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
67 context3d_->texImage2D( | |
68 GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0, | |
69 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
70 } | |
71 } | |
72 } | |
73 | |
74 void MailboxOutputSurface::DiscardBackbuffer() { | |
75 if (current_backing_.texture_id) { | |
76 context3d_->deleteTexture(current_backing_.texture_id); | |
77 current_backing_ = TransferableFrame(); | |
78 } | |
piman
2013/02/27 01:07:13
I think it would be good to destroy the FBO here.
no sievers
2013/02/27 21:07:40
Done.
| |
79 | |
80 while (returned_textures_.size()) { | |
81 context3d_->deleteTexture(returned_textures_.front().texture_id); | |
82 returned_textures_.pop(); | |
83 } | |
84 } | |
85 | |
86 void MailboxOutputSurface::Reshape(const gfx::Size& size) { | |
87 size_ = size; | |
88 DiscardBackbuffer(); | |
89 EnsureBackbuffer(); | |
90 } | |
91 | |
92 void MailboxOutputSurface::BindFramebuffer() { | |
93 EnsureBackbuffer(); | |
94 DCHECK(current_backing_.texture_id); | |
95 | |
96 if (!fbo_) | |
97 fbo_ = context3d_->createFramebuffer(); | |
98 context3d_->bindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
99 context3d_->framebufferTexture2D( | |
100 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | |
101 current_backing_.texture_id, 0); | |
102 } | |
103 | |
104 void MailboxOutputSurface::SendFrameToParentCompositor( | |
105 cc::CompositorFrame* frame) { | |
106 frame->gl_frame_data.reset(new GLFrameData()); | |
107 | |
108 DCHECK(!size_.IsEmpty()); | |
109 DCHECK(size_ == current_backing_.size); | |
110 DCHECK(!current_backing_.mailbox.isZero()); | |
111 | |
112 context3d_->framebufferTexture2D( | |
113 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); | |
114 context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id); | |
115 context3d_->produceTextureCHROMIUM( | |
116 GL_TEXTURE_2D, current_backing_.mailbox.name); | |
117 frame->gl_frame_data->mailbox = current_backing_.mailbox; | |
118 frame->gl_frame_data->size = current_backing_.size; | |
119 context3d_->flush(); | |
120 frame->gl_frame_data->sync_point = context3d_->insertSyncPoint(); | |
121 context3d_->deleteTexture(current_backing_.texture_id); | |
122 current_backing_ = TransferableFrame(); | |
123 CompositorOutputSurface::SendFrameToParentCompositor(frame); | |
124 } | |
125 | |
126 void MailboxOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) { | |
127 if (!ack.gl_frame_data->mailbox.isZero()) { | |
128 uint32 texture_id = context3d_->createTexture(); | |
129 TransferableFrame texture( | |
130 texture_id, ack.gl_frame_data->mailbox, ack.gl_frame_data->size); | |
131 | |
132 context3d_->bindTexture(GL_TEXTURE_2D, texture_id); | |
133 | |
134 // If the consumer is bouncing back the same texture (i.e. skipping the | |
135 // frame), we don't have to synchronize here (sync_point == 0). | |
136 if (ack.gl_frame_data->sync_point) | |
137 context3d_->waitSyncPoint(ack.gl_frame_data->sync_point); | |
138 | |
139 context3d_->consumeTextureCHROMIUM( | |
140 GL_TEXTURE_2D, ack.gl_frame_data->mailbox.name); | |
141 returned_textures_.push(texture); | |
142 } | |
143 CompositorOutputSurface::OnSwapAck(ack); | |
144 } | |
145 | |
146 void MailboxOutputSurface::SwapBuffers() { | |
147 } | |
148 | |
149 void MailboxOutputSurface::PostSubBuffer(const gfx::Rect& rect) { | |
150 NOTIMPLEMENTED() | |
151 << "Partial swap not supported with composite-to-mailbox yet."; | |
152 } | |
153 | |
154 } // namespace content | |
OLD | NEW |