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

Side by Side Diff: Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp

Issue 13642009: WebCore: Remove PLATFORM(WIN) files we do not use. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 /*
2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "GraphicsSurface.h"
22
23 #if USE(GRAPHICS_SURFACE) && OS(DARWIN)
24 #include "TextureMapperGL.h"
25 #include <CFNumber.h>
26 #include <CGLContext.h>
27 #include <CGLCurrent.h>
28 #include <CGLIOSurface.h>
29 #include <IOSurface/IOSurface.h>
30 #include <OpenGL/OpenGL.h>
31 #include <OpenGL/gl.h>
32 #include <mach/mach.h>
33
34 namespace WebCore {
35
36 static uint32_t createTexture(IOSurfaceRef handle)
37 {
38 GLuint texture = 0;
39 GLuint format = GL_BGRA;
40 GLuint type = GL_UNSIGNED_INT_8_8_8_8_REV;
41 GLuint internalFormat = GL_RGBA;
42 CGLContextObj context = CGLGetCurrentContext();
43 if (!context)
44 return 0;
45
46 GLint prevTexture;
47 glGetIntegerv(GL_TEXTURE_RECTANGLE_ARB, &prevTexture);
48
49 glGenTextures(1, &texture);
50 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
51 CGLError error = CGLTexImageIOSurface2D(context, GL_TEXTURE_RECTANGLE_ARB, i nternalFormat, IOSurfaceGetWidth(handle), IOSurfaceGetHeight(handle), format, ty pe, handle, 0);
52 if (error) {
53 glDeleteTextures(1, &texture);
54 texture = 0;
55 }
56
57 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, prevTexture);
58
59 return texture;
60 }
61
62 struct GraphicsSurfacePrivate {
63 public:
64 GraphicsSurfacePrivate(const GraphicsSurfaceToken& token, const IntSize& siz e)
65 : m_context(0)
66 , m_size(size)
67 , m_token(token)
68 , m_frontBufferTexture(0)
69 , m_frontBufferReadTexture(0)
70 , m_backBufferTexture(0)
71 , m_backBufferReadTexture(0)
72 , m_readFbo(0)
73 , m_drawFbo(0)
74 {
75 m_frontBuffer = IOSurfaceLookupFromMachPort(m_token.frontBufferHandle);
76 m_backBuffer = IOSurfaceLookupFromMachPort(m_token.backBufferHandle);
77 }
78
79 GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext, const I ntSize& size, GraphicsSurface::Flags flags)
80 : m_context(0)
81 , m_size(size)
82 , m_frontBufferTexture(0)
83 , m_frontBufferReadTexture(0)
84 , m_backBufferTexture(0)
85 , m_backBufferReadTexture(0)
86 , m_readFbo(0)
87 , m_drawFbo(0)
88 {
89 unsigned pixelFormat = 'BGRA';
90 unsigned bytesPerElement = 4;
91 int width = m_size.width();
92 int height = m_size.height();
93
94 unsigned long bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow , width * bytesPerElement);
95 if (!bytesPerRow)
96 return;
97
98 unsigned long allocSize = IOSurfaceAlignProperty(kIOSurfaceAllocSize, he ight * bytesPerRow);
99 if (!allocSize)
100 return;
101
102 const void *keys[6];
103 const void *values[6];
104 keys[0] = kIOSurfaceWidth;
105 values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
106 keys[1] = kIOSurfaceHeight;
107 values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
108 keys[2] = kIOSurfacePixelFormat;
109 values[2] = CFNumberCreate(0, kCFNumberIntType, &pixelFormat);
110 keys[3] = kIOSurfaceBytesPerElement;
111 values[3] = CFNumberCreate(0, kCFNumberIntType, &bytesPerElement);
112 keys[4] = kIOSurfaceBytesPerRow;
113 values[4] = CFNumberCreate(0, kCFNumberLongType, &bytesPerRow);
114 keys[5] = kIOSurfaceAllocSize;
115 values[5] = CFNumberCreate(0, kCFNumberLongType, &allocSize);
116
117 CFDictionaryRef dict = CFDictionaryCreate(0, keys, values, 6, &kCFTypeDi ctionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
118 for (unsigned i = 0; i < 6; i++)
119 CFRelease(values[i]);
120
121 m_frontBuffer = IOSurfaceCreate(dict);
122 m_backBuffer = IOSurfaceCreate(dict);
123
124 if (!(flags & GraphicsSurface::SupportsSharing))
125 return;
126
127 m_token = GraphicsSurfaceToken(IOSurfaceCreateMachPort(m_frontBuffer), I OSurfaceCreateMachPort(m_backBuffer));
128 }
129
130 ~GraphicsSurfacePrivate()
131 {
132 if (m_frontBufferTexture)
133 glDeleteTextures(1, &m_frontBufferTexture);
134
135 if (m_frontBufferReadTexture)
136 glDeleteTextures(1, &m_frontBufferReadTexture);
137
138 if (m_backBufferTexture)
139 glDeleteTextures(1, &m_backBufferTexture);
140
141 if (m_backBufferReadTexture)
142 glDeleteTextures(1, &m_backBufferReadTexture);
143
144 if (m_frontBuffer)
145 CFRelease(IOSurfaceRef(m_frontBuffer));
146
147 if (m_backBuffer)
148 CFRelease(IOSurfaceRef(m_backBuffer));
149
150 if (m_readFbo)
151 glDeleteFramebuffers(1, &m_readFbo);
152
153 if (m_drawFbo)
154 glDeleteFramebuffers(1, &m_drawFbo);
155
156 if (m_context)
157 CGLReleaseContext(m_context);
158
159 if (m_token.frontBufferHandle)
160 mach_port_deallocate(mach_task_self(), m_token.frontBufferHandle);
161 if (m_token.backBufferHandle)
162 mach_port_deallocate(mach_task_self(), m_token.backBufferHandle);
163
164 }
165
166 uint32_t swapBuffers()
167 {
168 std::swap(m_frontBuffer, m_backBuffer);
169 std::swap(m_frontBufferTexture, m_backBufferTexture);
170 std::swap(m_frontBufferReadTexture, m_backBufferReadTexture);
171
172 return IOSurfaceGetID(m_frontBuffer);
173 }
174
175 void makeCurrent()
176 {
177 m_detachedContext = CGLGetCurrentContext();
178
179 if (m_context)
180 CGLSetCurrentContext(m_context);
181 }
182
183 void doneCurrent()
184 {
185 CGLSetCurrentContext(m_detachedContext);
186 m_detachedContext = 0;
187 }
188
189 void copyFromTexture(uint32_t texture, const IntRect& sourceRect)
190 {
191 // FIXME: The following glFlush can possibly be replaced by using the GL _ARB_sync extension.
192 glFlush(); // Make sure the texture has actually been completely written in the original context.
193
194 makeCurrent();
195
196 int x = sourceRect.x();
197 int y = sourceRect.y();
198 int width = sourceRect.width();
199 int height = sourceRect.height();
200
201 glPushAttrib(GL_ALL_ATTRIB_BITS);
202 GLint previousFBO;
203 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousFBO);
204
205 if (!m_drawFbo)
206 glGenFramebuffers(1, &m_drawFbo);
207
208 if (!m_readFbo)
209 glGenFramebuffers(1, &m_readFbo);
210
211 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_readFbo);
212 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX TURE_2D, texture, 0);
213
214 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFbo);
215 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX TURE_RECTANGLE_ARB, backBufferTextureID(), 0);
216 glBlitFramebuffer(x, y, width, height, x, x+height, y+width, y, GL_COLOR _BUFFER_BIT, GL_LINEAR); // Flip the texture upside down.
217
218 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX TURE_RECTANGLE_ARB, 0, 0);
219 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX TURE_2D, 0, 0);
220 glBindFramebuffer(GL_FRAMEBUFFER, previousFBO);
221 glPopAttrib();
222
223 // Flushing the gl command buffer is necessary to ensure the texture has correctly been bound to the IOSurface.
224 glFlush();
225
226 swapBuffers();
227 doneCurrent();
228 }
229
230 GraphicsSurfaceToken token() const
231 {
232 return m_token;
233 }
234
235 uint32_t frontBufferTextureID()
236 {
237 if (!m_frontBufferReadTexture)
238 m_frontBufferReadTexture = createTexture(m_frontBuffer);
239
240 return m_frontBufferReadTexture;
241 }
242
243 uint32_t backBufferTextureID()
244 {
245 if (!m_backBufferTexture)
246 m_backBufferTexture = createTexture(m_backBuffer);
247
248 return m_backBufferTexture;
249 }
250
251 PlatformGraphicsSurface frontBuffer() const
252 {
253 return m_frontBuffer;
254 }
255
256 PlatformGraphicsSurface backBuffer() const
257 {
258 return m_backBuffer;
259 }
260
261 IntSize size() const
262 {
263 return m_size;
264 }
265
266 private:
267 CGLContextObj m_context;
268 IntSize m_size;
269 CGLContextObj m_detachedContext;
270 PlatformGraphicsSurface m_frontBuffer;
271 PlatformGraphicsSurface m_backBuffer;
272 uint32_t m_frontBufferTexture;
273 uint32_t m_frontBufferReadTexture;
274 uint32_t m_backBufferTexture;
275 uint32_t m_backBufferReadTexture;
276 uint32_t m_readFbo;
277 uint32_t m_drawFbo;
278 GraphicsSurfaceToken m_token;
279 };
280
281 GraphicsSurfaceToken GraphicsSurface::platformExport()
282 {
283 return m_private->token();
284 }
285
286 uint32_t GraphicsSurface::platformGetTextureID()
287 {
288 return m_private->frontBufferTextureID();
289 }
290
291 void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, cons t IntRect& targetRect, const IntPoint& offset)
292 {
293 glPushAttrib(GL_ALL_ATTRIB_BITS);
294 if (!m_fbo)
295 glGenFramebuffers(1, &m_fbo);
296 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
297 glBindTexture(target, id);
298 glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
299 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE _RECTANGLE_ARB, m_private->frontBufferTextureID(), 0);
300 glCopyTexSubImage2D(target, 0, targetRect.x(), targetRect.y(), offset.x(), o ffset.y(), targetRect.width(), targetRect.height());
301 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE _RECTANGLE_ARB, 0, 0);
302 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
303 glPopAttrib();
304
305 // According to IOSurface's documentation, glBindFramebuffer is the one trig gering an update of the surface's cache.
306 // If the web process starts rendering and unlocks the surface before this h appens, we might copy contents
307 // of the currently rendering frame on our texture instead of the previously completed frame.
308 // Flush the command buffer to reduce the odds of this happening, this would not be necessary with double buffering.
309 glFlush();
310 }
311
312 void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s ourceRect)
313 {
314 m_private->copyFromTexture(texture, sourceRect);
315 }
316
317 void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opaci ty)
318 {
319 IntSize size = m_private->size();
320 FloatRect rectOnContents(FloatPoint::zero(), size);
321 TransformationMatrix adjustedTransform = transform;
322 adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents, targetRect));
323 static_cast<TextureMapperGL*>(textureMapper)->drawTexture(m_private->frontBu fferTextureID(), TextureMapperGL::ShouldBlend | TextureMapperGL::ShouldUseARBTex tureRect, size, rectOnContents, adjustedTransform, opacity);
324 }
325
326 uint32_t GraphicsSurface::platformFrontBuffer() const
327 {
328 return IOSurfaceGetID(m_private->frontBuffer());
329 }
330
331 uint32_t GraphicsSurface::platformSwapBuffers()
332 {
333 return m_private->swapBuffers();
334 }
335
336 IntSize GraphicsSurface::platformSize() const
337 {
338 return m_private->size();
339 }
340
341 PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext)
342 {
343 // We currently disable support for CopyToTexture on Mac, because this is us ed for single buffered Tiles.
344 // The single buffered nature of this requires a call to glFlush, as describ ed in platformCopyToTexture.
345 // This call blocks the GPU for about 40ms, which makes smooth animations im possible.
346 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
347 return PassRefPtr<GraphicsSurface>();
348
349 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)) ;
350 surface->m_private = new GraphicsSurfacePrivate(shareContext, size, flags);
351
352 if (!surface->m_private->frontBuffer() || !surface->m_private->backBuffer())
353 return PassRefPtr<GraphicsSurface>();
354
355 return surface;
356 }
357
358 PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
359 {
360 // We currently disable support for CopyToTexture on Mac, because this is us ed for single buffered Tiles.
361 // The single buffered nature of this requires a call to glFlush, as describ ed in platformCopyToTexture.
362 // This call blocks the GPU for about 40ms, which makes smooth animations im possible.
363 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
364 return PassRefPtr<GraphicsSurface>();
365
366 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)) ;
367 surface->m_private = new GraphicsSurfacePrivate(token, size);
368
369 if (!surface->m_private->frontBuffer() || !surface->m_private->backBuffer())
370 return PassRefPtr<GraphicsSurface>();
371
372 return surface;
373 }
374
375 static int ioSurfaceLockOptions(int lockOptions)
376 {
377 int options = 0;
378 if (lockOptions & GraphicsSurface::ReadOnly)
379 options |= kIOSurfaceLockReadOnly;
380 if (!(lockOptions & GraphicsSurface::RetainPixels))
381 options |= kIOSurfaceLockAvoidSync;
382
383 return options;
384 }
385
386 char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, Lock Options lockOptions)
387 {
388 // Locking is only necessary for single buffered use.
389 // In this case we only have a front buffer, so we only lock this one.
390 m_lockOptions = lockOptions;
391 IOReturn status = IOSurfaceLock(m_private->frontBuffer(), ioSurfaceLockOptio ns(m_lockOptions), 0);
392 if (status == kIOReturnCannotLock) {
393 m_lockOptions |= RetainPixels;
394 IOSurfaceLock(m_private->frontBuffer(), ioSurfaceLockOptions(m_lockOptio ns), 0);
395 }
396
397 int stride = IOSurfaceGetBytesPerRow(m_private->frontBuffer());
398 if (outputStride)
399 *outputStride = stride;
400
401 char* base = static_cast<char*>(IOSurfaceGetBaseAddress(m_private->frontBuff er()));
402
403 return base + stride * rect.y() + rect.x() * 4;
404 }
405
406 void GraphicsSurface::platformUnlock()
407 {
408 IOSurfaceUnlock(m_private->frontBuffer(), ioSurfaceLockOptions(m_lockOptions ), 0);
409 }
410
411 void GraphicsSurface::platformDestroy()
412 {
413 if (m_fbo)
414 glDeleteFramebuffers(1, &m_fbo);
415 if (m_private)
416 delete m_private;
417 m_private = 0;
418 }
419
420 }
421 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698