Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: chrome/browser/renderer_host/accelerated_surface_container_mac.cc

Issue 6532073: Move core pieces of browser\renderer_host to src\content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/accelerated_surface_container_mac.h"
6
7 #include "app/surface/io_surface_support_mac.h"
8 #include "base/logging.h"
9 #include "chrome/browser/renderer_host/accelerated_surface_container_manager_mac .h"
10 #include "webkit/plugins/npapi/webplugin.h"
11
12 AcceleratedSurfaceContainerMac::AcceleratedSurfaceContainerMac(
13 AcceleratedSurfaceContainerManagerMac* manager,
14 bool opaque)
15 : manager_(manager),
16 opaque_(opaque),
17 surface_id_(0),
18 width_(0),
19 height_(0),
20 texture_(0),
21 texture_needs_upload_(true),
22 texture_pending_deletion_(0),
23 visible_(false),
24 was_painted_to_(false) {
25 }
26
27 AcceleratedSurfaceContainerMac::~AcceleratedSurfaceContainerMac() {
28 }
29
30 void AcceleratedSurfaceContainerMac::SetSizeAndIOSurface(
31 int32 width,
32 int32 height,
33 uint64 io_surface_identifier) {
34 // Ignore |io_surface_identifier|: The surface hasn't been painted to and
35 // only contains garbage data. Update the surface in |set_was_painted_to()|
36 // instead.
37 width_ = width;
38 height_ = height;
39 }
40
41 void AcceleratedSurfaceContainerMac::SetSizeAndTransportDIB(
42 int32 width,
43 int32 height,
44 TransportDIB::Handle transport_dib) {
45 if (TransportDIB::is_valid(transport_dib)) {
46 transport_dib_.reset(TransportDIB::Map(transport_dib));
47 EnqueueTextureForDeletion();
48 width_ = width;
49 height_ = height;
50 }
51 }
52
53 void AcceleratedSurfaceContainerMac::SetGeometry(
54 const webkit::npapi::WebPluginGeometry& geom) {
55 visible_ = geom.visible;
56 if (geom.rects_valid)
57 clip_rect_ = geom.clip_rect;
58 }
59
60 void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) {
61 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
62 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
63 if (texture_pending_deletion_) {
64 // Clean up an old texture object. This is essentially a pre-emptive
65 // cleanup, as the resources will be released when the OpenGL context
66 // associated with our containing NSView is destroyed. However, if we
67 // resize a plugin often, we might generate a lot of textures, so we
68 // should try to eagerly reclaim their resources. Note also that the
69 // OpenGL context must be current when performing the deletion, and it
70 // seems risky to make the OpenGL context current at an arbitrary point
71 // in time, which is why the deletion does not occur in the container's
72 // destructor.
73 glDeleteTextures(1, &texture_pending_deletion_);
74 texture_pending_deletion_ = 0;
75 }
76 if (!texture_) {
77 if ((io_surface_support && !surface_.get()) ||
78 (!io_surface_support && !transport_dib_.get()))
79 return;
80 glGenTextures(1, &texture_);
81 glBindTexture(target, texture_);
82 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
83 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
84 if (io_surface_support) {
85 texture_needs_upload_ = true;
86 } else {
87 // Reserve space on the card for the actual texture upload, done with the
88 // glTexSubImage2D() call, below.
89 glTexImage2D(target,
90 0, // mipmap level 0
91 GL_RGBA, // internal format
92 width_,
93 height_,
94 0, // no border
95 GL_BGRA, // The GPU plugin read BGRA pixels
96 GL_UNSIGNED_INT_8_8_8_8_REV,
97 NULL); // No data, this call just reserves room.
98 }
99 }
100
101 // When using an IOSurface, the texture does not need to be repeatedly
102 // uploaded, just when we've been told we have to.
103 if (io_surface_support && texture_needs_upload_) {
104 DCHECK(surface_.get());
105 glBindTexture(target, texture_);
106 // Don't think we need to identify a plane.
107 GLuint plane = 0;
108 io_surface_support->CGLTexImageIOSurface2D(context,
109 target,
110 GL_RGBA,
111 surface_width_,
112 surface_height_,
113 GL_BGRA,
114 GL_UNSIGNED_INT_8_8_8_8_REV,
115 surface_.get(),
116 plane);
117 texture_needs_upload_ = false;
118 }
119 // If using TransportDIBs, the texture needs to be uploaded every frame.
120 if (transport_dib_.get() != NULL) {
121 void* pixel_memory = transport_dib_->memory();
122 if (pixel_memory) {
123 glBindTexture(target, texture_);
124 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Needed for NPOT textures.
125 glTexSubImage2D(target,
126 0, // mipmap level 0
127 0, // x-offset
128 0, // y-offset
129 width_,
130 height_,
131 GL_BGRA, // The GPU plugin gave us BGRA pixels
132 GL_UNSIGNED_INT_8_8_8_8_REV,
133 pixel_memory);
134 }
135 }
136
137 if (texture_) {
138 int texture_width = io_surface_support ? surface_width_ : width_;
139 int texture_height = io_surface_support ? surface_height_ : height_;
140
141 // TODO(kbr): convert this to use only OpenGL ES 2.0 functionality.
142
143 // TODO(kbr): may need to pay attention to cutout rects.
144 int clipX = clip_rect_.x();
145 int clipY = clip_rect_.y();
146 int clipWidth = clip_rect_.width();
147 int clipHeight = clip_rect_.height();
148
149 if (clipX + clipWidth > texture_width)
150 clipWidth = texture_width - clipX;
151 if (clipY + clipHeight > texture_height)
152 clipHeight = texture_height - clipY;
153
154 if (opaque_) {
155 // Pepper 3D's output is currently considered opaque even if the
156 // program draws pixels with alpha less than 1. In order to have
157 // this effect, we need to drop the alpha channel of the input,
158 // replacing it with alpha = 1.
159
160 // First fill the rectangle with alpha=1.
161 glColorMask(false, false, false, true);
162 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
163 glBegin(GL_TRIANGLE_STRIP);
164 glVertex3f(0, 0, 0);
165 glVertex3f(clipWidth, 0, 0);
166 glVertex3f(0, clipHeight, 0);
167 glVertex3f(clipWidth, clipHeight, 0);
168 glEnd();
169
170 // Now draw the color channels from the incoming texture.
171 glColorMask(true, true, true, false);
172 // This call shouldn't be necessary -- we are using the GL_REPLACE
173 // texture environment mode -- but it appears to be.
174 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
175 } else {
176 glColorMask(true, true, true, true);
177 }
178
179 // Draw the color channels from the incoming texture.
180 glBindTexture(target, texture_);
181 glEnable(target);
182 glBegin(GL_TRIANGLE_STRIP);
183
184 glTexCoord2f(clipX, texture_height - clipY);
185 glVertex3f(0, 0, 0);
186
187 glTexCoord2f(clipX + clipWidth, texture_height - clipY);
188 glVertex3f(clipWidth, 0, 0);
189
190 glTexCoord2f(clipX, texture_height - clipY - clipHeight);
191 glVertex3f(0, clipHeight, 0);
192
193 glTexCoord2f(clipX + clipWidth, texture_height - clipY - clipHeight);
194 glVertex3f(clipWidth, clipHeight, 0);
195
196 glEnd();
197 glDisable(target);
198 }
199 }
200
201 bool AcceleratedSurfaceContainerMac::ShouldBeVisible() const {
202 return visible_ && was_painted_to_ && !clip_rect_.IsEmpty();
203 }
204
205 void AcceleratedSurfaceContainerMac::set_was_painted_to(uint64 surface_id) {
206 if (surface_id && (!surface_ || surface_id != surface_id_)) {
207 // Keep the surface that was most recently painted to around.
208 if (IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize()) {
209 CFTypeRef surface = io_surface_support->IOSurfaceLookup(
210 static_cast<uint32>(surface_id));
211 // Can fail if IOSurface with that ID was already released by the
212 // gpu process or the plugin process. We will get a |set_was_painted_to()|
213 // message with a new surface soon in that case.
214 if (surface) {
215 surface_.reset(surface);
216 surface_id_ = surface_id;
217 surface_width_ = io_surface_support->IOSurfaceGetWidth(surface_);
218 surface_height_ = io_surface_support->IOSurfaceGetHeight(surface_);
219 EnqueueTextureForDeletion();
220 }
221 }
222 }
223 was_painted_to_ = true;
224 }
225
226 void AcceleratedSurfaceContainerMac::EnqueueTextureForDeletion() {
227 if (texture_) {
228 DCHECK(texture_pending_deletion_ == 0);
229 texture_pending_deletion_ = texture_;
230 texture_ = 0;
231 }
232 }
233
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698