| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) | |
| 3 Copyright (C) 2013 Intel Corporation. | |
| 4 | |
| 5 This library is free software; you can redistribute it and/or | |
| 6 modify it under the terms of the GNU Library General Public | |
| 7 License as published by the Free Software Foundation; either | |
| 8 version 2 of the License, or (at your option) any later version. | |
| 9 | |
| 10 This library is distributed in the hope that it will be useful, | |
| 11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 Library General Public License for more details. | |
| 14 | |
| 15 You should have received a copy of the GNU Library General Public License | |
| 16 along with this library; see the file COPYING.LIB. If not, write to | |
| 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| 18 Boston, MA 02110-1301, USA. | |
| 19 */ | |
| 20 | |
| 21 #include "config.h" | |
| 22 #include "GraphicsSurface.h" | |
| 23 | |
| 24 #if USE(GRAPHICS_SURFACE) | |
| 25 | |
| 26 #include "NotImplemented.h" | |
| 27 #include "TextureMapperGL.h" | |
| 28 | |
| 29 #if PLATFORM(QT) | |
| 30 // Qt headers must be included before glx headers. | |
| 31 #include <QGuiApplication> | |
| 32 #include <QOpenGLContext> | |
| 33 #include <qpa/qplatformnativeinterface.h> | |
| 34 #include <GL/glext.h> | |
| 35 #include <GL/glx.h> | |
| 36 #else | |
| 37 #include <opengl/GLDefs.h> | |
| 38 #endif | |
| 39 | |
| 40 #include "GLXConfigSelector.h" | |
| 41 | |
| 42 namespace WebCore { | |
| 43 | |
| 44 static PFNGLXBINDTEXIMAGEEXTPROC pGlXBindTexImageEXT = 0; | |
| 45 static PFNGLXRELEASETEXIMAGEEXTPROC pGlXReleaseTexImageEXT = 0; | |
| 46 static PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer = 0; | |
| 47 static PFNGLBLITFRAMEBUFFERPROC pGlBlitFramebuffer = 0; | |
| 48 static PFNGLGENFRAMEBUFFERSPROC pGlGenFramebuffers = 0; | |
| 49 static PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers = 0; | |
| 50 static PFNGLFRAMEBUFFERTEXTURE2DPROC pGlFramebufferTexture2D = 0; | |
| 51 | |
| 52 static int glxAttributes[] = { | |
| 53 GLX_TEXTURE_FORMAT_EXT, | |
| 54 GLX_TEXTURE_FORMAT_RGBA_EXT, | |
| 55 GLX_TEXTURE_TARGET_EXT, | |
| 56 GLX_TEXTURE_2D_EXT, | |
| 57 0 | |
| 58 }; | |
| 59 | |
| 60 static bool isMesaGLX() | |
| 61 { | |
| 62 static bool isMesa = !!strstr(glXGetClientString(X11Helper::nativeDisplay(),
GLX_VENDOR), "Mesa"); | |
| 63 return isMesa; | |
| 64 } | |
| 65 | |
| 66 struct GraphicsSurfacePrivate { | |
| 67 GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext = 0) | |
| 68 : m_xPixmap(0) | |
| 69 , m_glxPixmap(0) | |
| 70 , m_surface(0) | |
| 71 , m_glxSurface(0) | |
| 72 , m_glContext(0) | |
| 73 , m_detachedContext(0) | |
| 74 , m_detachedSurface(0) | |
| 75 , m_isReceiver(false) | |
| 76 , m_texture(0) | |
| 77 { | |
| 78 GLXContext shareContextObject = 0; | |
| 79 | |
| 80 #if PLATFORM(QT) | |
| 81 if (shareContext) { | |
| 82 QPlatformNativeInterface* nativeInterface = QGuiApplication::platfor
mNativeInterface(); | |
| 83 shareContextObject = static_cast<GLXContext>(nativeInterface->native
ResourceForContext(QByteArrayLiteral("glxcontext"), shareContext)); | |
| 84 if (!shareContextObject) | |
| 85 return; | |
| 86 } | |
| 87 #else | |
| 88 UNUSED_PARAM(shareContext); | |
| 89 #endif | |
| 90 | |
| 91 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatfor
mSurface::DoubleBuffered | | |
| 92 GLPlatformSurface::SupportAlpha; | |
| 93 m_configSelector = adoptPtr(new GLXConfigSelector(sharedSurfaceAttribute
s)); | |
| 94 | |
| 95 if (!m_configSelector->surfaceContextConfig()) { | |
| 96 clear(); | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 // Create a GLX context for OpenGL rendering | |
| 101 m_glContext = glXCreateNewContext(display(), m_configSelector->surfaceCo
ntextConfig(), GLX_RGBA_TYPE, shareContextObject, true); | |
| 102 } | |
| 103 | |
| 104 GraphicsSurfacePrivate(uint32_t winId) | |
| 105 : m_xPixmap(0) | |
| 106 , m_glxPixmap(0) | |
| 107 , m_surface(winId) | |
| 108 , m_glxSurface(0) | |
| 109 , m_glContext(0) | |
| 110 , m_detachedContext(0) | |
| 111 , m_detachedSurface(0) | |
| 112 , m_isReceiver(true) | |
| 113 , m_texture(0) | |
| 114 { | |
| 115 } | |
| 116 | |
| 117 ~GraphicsSurfacePrivate() | |
| 118 { | |
| 119 clear(); | |
| 120 } | |
| 121 | |
| 122 uint32_t createSurface(const IntSize& size) | |
| 123 { | |
| 124 if (!display() || !m_configSelector) | |
| 125 return 0; | |
| 126 | |
| 127 GLXFBConfig config = m_configSelector->surfaceContextConfig(); | |
| 128 OwnPtrX11<XVisualInfo> visInfo(m_configSelector->visualInfo(config)); | |
| 129 | |
| 130 if (!visInfo.get()) { | |
| 131 clear(); | |
| 132 return 0; | |
| 133 } | |
| 134 | |
| 135 X11Helper::createOffScreenWindow(&m_surface, *visInfo.get(), size); | |
| 136 | |
| 137 if (!m_surface) { | |
| 138 clear(); | |
| 139 return 0; | |
| 140 } | |
| 141 | |
| 142 m_glxSurface = glXCreateWindow(display(), config, m_surface, 0); | |
| 143 return m_surface; | |
| 144 } | |
| 145 | |
| 146 void createPixmap(uint32_t winId) | |
| 147 { | |
| 148 XWindowAttributes attr; | |
| 149 if (!XGetWindowAttributes(display(), winId, &attr)) | |
| 150 return; | |
| 151 | |
| 152 // Ensure that the window is mapped. | |
| 153 if (attr.map_state == IsUnmapped || attr.map_state == IsUnviewable) | |
| 154 return; | |
| 155 | |
| 156 ScopedXPixmapCreationErrorHandler handler; | |
| 157 m_size = IntSize(attr.width, attr.height); | |
| 158 | |
| 159 XRenderPictFormat* format = XRenderFindVisualFormat(display(), attr.visu
al); | |
| 160 bool hasAlpha = (format->type == PictTypeDirect && format->direct.alphaM
ask); | |
| 161 m_xPixmap = XCompositeNameWindowPixmap(display(), winId); | |
| 162 glxAttributes[1] = (format->depth == 32 && hasAlpha) ? GLX_TEXTURE_FORMA
T_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT; | |
| 163 | |
| 164 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatfor
mSurface::Default; | |
| 165 if (hasAlpha) | |
| 166 sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha; | |
| 167 | |
| 168 if (!m_configSelector) | |
| 169 m_configSelector = adoptPtr(new GLXConfigSelector(sharedSurfaceAttri
butes)); | |
| 170 | |
| 171 m_glxPixmap = glXCreatePixmap(display(), m_configSelector->surfaceClient
Config(format->depth, XVisualIDFromVisual(attr.visual)), m_xPixmap, glxAttribute
s); | |
| 172 | |
| 173 if (!handler.isValidOperation()) | |
| 174 clear(); | |
| 175 else { | |
| 176 uint inverted = 0; | |
| 177 glXQueryDrawable(display(), m_glxPixmap, GLX_Y_INVERTED_EXT, &invert
ed); | |
| 178 m_flags = !!inverted ? TextureMapperGL::ShouldFlipTexture : 0; | |
| 179 | |
| 180 if (hasAlpha) | |
| 181 m_flags |= TextureMapperGL::ShouldBlend; | |
| 182 } | |
| 183 } | |
| 184 | |
| 185 void makeCurrent() | |
| 186 { | |
| 187 m_detachedContext = glXGetCurrentContext(); | |
| 188 m_detachedSurface = glXGetCurrentDrawable(); | |
| 189 if (m_surface && m_glContext) | |
| 190 glXMakeCurrent(display(), m_surface, m_glContext); | |
| 191 } | |
| 192 | |
| 193 void doneCurrent() | |
| 194 { | |
| 195 if (m_detachedContext) | |
| 196 glXMakeCurrent(display(), m_detachedSurface, m_detachedContext); | |
| 197 m_detachedContext = 0; | |
| 198 } | |
| 199 | |
| 200 void swapBuffers() | |
| 201 { | |
| 202 if (isReceiver()) { | |
| 203 if (isMesaGLX() && textureID()) { | |
| 204 glBindTexture(GL_TEXTURE_2D, textureID()); | |
| 205 // Mesa doesn't re-bind texture to the front buffer on glXSwapBu
fer | |
| 206 // Manually release previous lock and rebind texture to surface
to ensure frame updates. | |
| 207 pGlXReleaseTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT); | |
| 208 pGlXBindTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT, 0); | |
| 209 } | |
| 210 | |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 GLXContext glContext = glXGetCurrentContext(); | |
| 215 | |
| 216 if (m_surface && glContext) { | |
| 217 GLint oldFBO; | |
| 218 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO); | |
| 219 pGlBindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 220 glXSwapBuffers(display(), m_surface); | |
| 221 pGlBindFramebuffer(GL_FRAMEBUFFER, oldFBO); | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 void copyFromTexture(uint32_t texture, const IntRect& sourceRect) | |
| 226 { | |
| 227 makeCurrent(); | |
| 228 int x = sourceRect.x(); | |
| 229 int y = sourceRect.y(); | |
| 230 int width = sourceRect.width(); | |
| 231 int height = sourceRect.height(); | |
| 232 | |
| 233 glPushAttrib(GL_ALL_ATTRIB_BITS); | |
| 234 GLint previousFBO; | |
| 235 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousFBO); | |
| 236 | |
| 237 GLuint originFBO; | |
| 238 pGlGenFramebuffers(1, &originFBO); | |
| 239 pGlBindFramebuffer(GL_READ_FRAMEBUFFER, originFBO); | |
| 240 glBindTexture(GL_TEXTURE_2D, texture); | |
| 241 pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TE
XTURE_2D, texture, 0); | |
| 242 | |
| 243 pGlBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | |
| 244 pGlBlitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BU
FFER_BIT, GL_LINEAR); | |
| 245 | |
| 246 pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TE
XTURE_2D, 0, 0); | |
| 247 glBindTexture(GL_TEXTURE_2D, 0); | |
| 248 pGlBindFramebuffer(GL_FRAMEBUFFER, previousFBO); | |
| 249 pGlDeleteFramebuffers(1, &originFBO); | |
| 250 | |
| 251 glPopAttrib(); | |
| 252 | |
| 253 swapBuffers(); | |
| 254 doneCurrent(); | |
| 255 } | |
| 256 | |
| 257 Display* display() const { return X11Helper::nativeDisplay(); } | |
| 258 | |
| 259 GLXPixmap glxPixmap() const | |
| 260 { | |
| 261 if (!m_glxPixmap && m_surface) | |
| 262 const_cast<GraphicsSurfacePrivate*>(this)->createPixmap(m_surface); | |
| 263 return m_glxPixmap; | |
| 264 } | |
| 265 | |
| 266 IntSize size() const | |
| 267 { | |
| 268 if (m_size.isEmpty()) { | |
| 269 XWindowAttributes attr; | |
| 270 if (XGetWindowAttributes(display(), m_surface, &attr)) | |
| 271 const_cast<GraphicsSurfacePrivate*>(this)->m_size = IntSize(attr
.width, attr.height); | |
| 272 } | |
| 273 return m_size; | |
| 274 } | |
| 275 | |
| 276 bool isReceiver() const { return m_isReceiver; } | |
| 277 | |
| 278 TextureMapperGL::Flags flags() const { return m_flags; } | |
| 279 | |
| 280 Window surface() const { return m_surface; } | |
| 281 | |
| 282 GLuint textureID() const | |
| 283 { | |
| 284 if (m_texture) | |
| 285 return m_texture; | |
| 286 | |
| 287 GLXPixmap pixmap = glxPixmap(); | |
| 288 if (!pixmap) | |
| 289 return 0; | |
| 290 | |
| 291 GLuint texture; | |
| 292 glGenTextures(1, &texture); | |
| 293 glBindTexture(GL_TEXTURE_2D, texture); | |
| 294 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 295 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 298 pGlXBindTexImageEXT(display(), pixmap, GLX_FRONT_EXT, 0); | |
| 299 const_cast<GraphicsSurfacePrivate*>(this)->m_texture = texture; | |
| 300 | |
| 301 return texture; | |
| 302 } | |
| 303 private: | |
| 304 void clear() | |
| 305 { | |
| 306 if (m_texture) { | |
| 307 pGlXReleaseTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT); | |
| 308 glDeleteTextures(1, &m_texture); | |
| 309 } | |
| 310 | |
| 311 if (m_glxPixmap) { | |
| 312 glXDestroyPixmap(display(), m_glxPixmap); | |
| 313 m_glxPixmap = 0; | |
| 314 } | |
| 315 | |
| 316 if (m_xPixmap) { | |
| 317 XFreePixmap(display(), m_xPixmap); | |
| 318 m_xPixmap = 0; | |
| 319 } | |
| 320 | |
| 321 // Client doesn't own the window. Delete surface only on writing side. | |
| 322 if (!m_isReceiver && m_surface) { | |
| 323 XDestroyWindow(display(), m_surface); | |
| 324 m_surface = 0; | |
| 325 } | |
| 326 | |
| 327 if (m_glContext) { | |
| 328 glXDestroyContext(display(), m_glContext); | |
| 329 m_glContext = 0; | |
| 330 } | |
| 331 | |
| 332 if (m_configSelector) | |
| 333 m_configSelector = nullptr; | |
| 334 } | |
| 335 | |
| 336 IntSize m_size; | |
| 337 Pixmap m_xPixmap; | |
| 338 GLXPixmap m_glxPixmap; | |
| 339 uint32_t m_surface; | |
| 340 Window m_glxSurface; | |
| 341 GLXContext m_glContext; | |
| 342 GLXContext m_detachedContext; | |
| 343 GLXDrawable m_detachedSurface; | |
| 344 OwnPtr<GLXConfigSelector> m_configSelector; | |
| 345 bool m_isReceiver; | |
| 346 TextureMapperGL::Flags m_flags; | |
| 347 GLuint m_texture; | |
| 348 }; | |
| 349 | |
| 350 static bool resolveGLMethods() | |
| 351 { | |
| 352 static bool resolved = false; | |
| 353 if (resolved) | |
| 354 return true; | |
| 355 pGlXBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glXGetProc
Address(reinterpret_cast<const GLubyte*>("glXBindTexImageEXT"))); | |
| 356 pGlXReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glXG
etProcAddress(reinterpret_cast<const GLubyte*>("glXReleaseTexImageEXT"))); | |
| 357 pGlBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(glXGetProcAd
dress(reinterpret_cast<const GLubyte*>("glBindFramebuffer"))); | |
| 358 pGlBlitFramebuffer = reinterpret_cast<PFNGLBLITFRAMEBUFFERPROC>(glXGetProcAd
dress(reinterpret_cast<const GLubyte*>("glBlitFramebuffer"))); | |
| 359 | |
| 360 pGlGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(glXGetProcAd
dress(reinterpret_cast<const GLubyte*>("glGenFramebuffers"))); | |
| 361 pGlDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(glXGet
ProcAddress(reinterpret_cast<const GLubyte*>("glDeleteFramebuffers"))); | |
| 362 pGlFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(gl
XGetProcAddress(reinterpret_cast<const GLubyte*>("glFramebufferTexture2D"))); | |
| 363 resolved = pGlBlitFramebuffer && pGlBindFramebuffer && pGlXBindTexImageEXT &
& pGlXReleaseTexImageEXT; | |
| 364 | |
| 365 return resolved; | |
| 366 } | |
| 367 | |
| 368 GraphicsSurfaceToken GraphicsSurface::platformExport() | |
| 369 { | |
| 370 return GraphicsSurfaceToken(m_private->surface()); | |
| 371 } | |
| 372 | |
| 373 uint32_t GraphicsSurface::platformGetTextureID() | |
| 374 { | |
| 375 return m_private->textureID(); | |
| 376 } | |
| 377 | |
| 378 void GraphicsSurface::platformCopyToGLTexture(uint32_t /*target*/, uint32_t /*id
*/, const IntRect& /*targetRect*/, const IntPoint& /*offset*/) | |
| 379 { | |
| 380 // This is not supported by GLX/Xcomposite. | |
| 381 } | |
| 382 | |
| 383 void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s
ourceRect) | |
| 384 { | |
| 385 m_private->copyFromTexture(texture, sourceRect); | |
| 386 } | |
| 387 | |
| 388 void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper,
const FloatRect& targetRect, const TransformationMatrix& transform, float opaci
ty) | |
| 389 { | |
| 390 IntSize size = m_private->size(); | |
| 391 if (size.isEmpty()) | |
| 392 return; | |
| 393 uint32_t texture = platformGetTextureID(); | |
| 394 if (!texture) | |
| 395 return; | |
| 396 | |
| 397 FloatRect rectOnContents(FloatPoint::zero(), size); | |
| 398 TransformationMatrix adjustedTransform = transform; | |
| 399 adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents,
targetRect)); | |
| 400 static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private
->flags(), size, rectOnContents, adjustedTransform, opacity); | |
| 401 } | |
| 402 | |
| 403 uint32_t GraphicsSurface::platformFrontBuffer() const | |
| 404 { | |
| 405 return 0; | |
| 406 } | |
| 407 | |
| 408 uint32_t GraphicsSurface::platformSwapBuffers() | |
| 409 { | |
| 410 m_private->swapBuffers(); | |
| 411 return 0; | |
| 412 } | |
| 413 | |
| 414 IntSize GraphicsSurface::platformSize() const | |
| 415 { | |
| 416 return m_private->size(); | |
| 417 } | |
| 418 | |
| 419 PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size,
Flags flags, const PlatformGraphicsContext3D shareContext) | |
| 420 { | |
| 421 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface
if this is requested. | |
| 422 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has
a front and a back buffer. | |
| 423 // Therefore single buffered GraphicsSurfaces are not supported. | |
| 424 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered) | |
| 425 return PassRefPtr<GraphicsSurface>(); | |
| 426 | |
| 427 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags))
; | |
| 428 | |
| 429 surface->m_private = new GraphicsSurfacePrivate(shareContext); | |
| 430 if (!resolveGLMethods()) | |
| 431 return PassRefPtr<GraphicsSurface>(); | |
| 432 | |
| 433 surface->m_private->createSurface(size); | |
| 434 | |
| 435 return surface; | |
| 436 } | |
| 437 | |
| 438 PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size,
Flags flags, const GraphicsSurfaceToken& token) | |
| 439 { | |
| 440 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface
if this is requested. | |
| 441 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has
a front and a back buffer. | |
| 442 // Therefore single buffered GraphicsSurfaces are not supported. | |
| 443 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered) | |
| 444 return PassRefPtr<GraphicsSurface>(); | |
| 445 | |
| 446 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags))
; | |
| 447 | |
| 448 surface->m_private = new GraphicsSurfacePrivate(token.frontBufferHandle); | |
| 449 if (!resolveGLMethods()) | |
| 450 return PassRefPtr<GraphicsSurface>(); | |
| 451 | |
| 452 return surface; | |
| 453 } | |
| 454 | |
| 455 char* GraphicsSurface::platformLock(const IntRect&, int* /*outputStride*/, LockO
ptions) | |
| 456 { | |
| 457 // GraphicsSurface is currently only being used for WebGL, which does not re
quire this locking mechanism. | |
| 458 return 0; | |
| 459 } | |
| 460 | |
| 461 void GraphicsSurface::platformUnlock() | |
| 462 { | |
| 463 // GraphicsSurface is currently only being used for WebGL, which does not re
quire this locking mechanism. | |
| 464 } | |
| 465 | |
| 466 void GraphicsSurface::platformDestroy() | |
| 467 { | |
| 468 delete m_private; | |
| 469 m_private = 0; | |
| 470 } | |
| 471 | |
| 472 #if !PLATFORM(QT) | |
| 473 PassOwnPtr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize&,
char*, int) | |
| 474 { | |
| 475 notImplemented(); | |
| 476 return nullptr; | |
| 477 } | |
| 478 | |
| 479 PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect&) | |
| 480 { | |
| 481 notImplemented(); | |
| 482 return 0; | |
| 483 } | |
| 484 #endif | |
| 485 } | |
| 486 #endif | |
| OLD | NEW |