void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject, ExceptionCode& ec) { UNUSED_PARAM(ec); if (m_context->isContextLost()) return; if (arrayObject && arrayObject->context() != m_context) { m_context->graphicsContext3D()->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); return; } Extensions3D* extensions = m_context->graphicsContext3D()->getExtensions(); if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) { extensions->bindVertexArrayOES(arrayObject->object()); arrayObject->setHasEverBeenBound(); m_context->setBoundVertexArrayObject(arrayObject); } else { extensions->bindVertexArrayOES(0); m_context->setBoundVertexArrayObject(0); } m_context->cleanupAfterGraphicsCall(false); }
void GraphicsContext3DPrivate::initializeANGLE() { ShBuiltInResources ANGLEResources; ShInitBuiltInResources(&ANGLEResources); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors); m_context->getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors); m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits); m_context->getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors); // Always set to 1 for OpenGL ES. ANGLEResources.MaxDrawBuffers = 1; Extensions3D* extensions = m_context->getExtensions(); if (extensions->supports("GL_ARB_texture_rectangle")) ANGLEResources.ARB_texture_rectangle = 1; GC3Dint range[2], precision; m_context->getShaderPrecisionFormat(GraphicsContext3D::FRAGMENT_SHADER, GraphicsContext3D::HIGH_FLOAT, range, &precision); ANGLEResources.FragmentPrecisionHigh = (range[0] || range[1] || precision); m_context->m_compiler.setResources(ANGLEResources); }
void GraphicsContext3D::validateAttributes() { Extensions3D* extensions = getExtensions(); if (m_attrs.stencil) { const char* packedDepthStencilExtension = isGLES2Compliant() ? "GL_OES_packed_depth_stencil" : "GL_EXT_packed_depth_stencil"; if (extensions->supports(packedDepthStencilExtension)) { extensions->ensureEnabled(packedDepthStencilExtension); // Force depth if stencil is true. m_attrs.depth = true; } else m_attrs.stencil = false; } if (m_attrs.antialias) { bool isValidVendor = true; // Currently in Mac we only turn on antialias if vendor is NVIDIA, // or if ATI and on 10.7.2 and above. const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR)); if (!std::strstr(vendor, "NVIDIA") && !(std::strstr(vendor, "ATI") && systemAllowsMultisamplingOnATICards())) isValidVendor = false; if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant()) m_attrs.antialias = false; else extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); } }
bool WebGLDepthTexture::supported(GraphicsContext3D* context) { Extensions3D* extensions = context->getExtensions(); return extensions->supports("GL_CHROMIUM_depth_texture") || extensions->supports("GL_OES_depth_texture") || extensions->supports("GL_ARB_depth_texture"); }
void WebMediaPlayerClientImpl::paintOnAndroid(WebCore::GraphicsContext* context, WebCore::GraphicsContext3D* context3D, const IntRect& rect, uint8_t alpha) { if (!context || !context3D || !m_webMediaPlayer || context->paintingDisabled()) return; Extensions3D* extensions = context3D->extensions(); if (!extensions || !extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy") || !context3D->makeContextCurrent()) return; // Copy video texture into a RGBA texture based bitmap first as video texture on Android is GL_TEXTURE_EXTERNAL_OES // which is not supported by Skia yet. The bitmap's size needs to be the same as the video and use naturalSize() here. // Check if we could reuse existing texture based bitmap. // Otherwise, release existing texture based bitmap and allocate a new one based on video size. if (!ensureTextureBackedSkBitmap(context3D->grContext(), m_bitmap, naturalSize(), kTopLeft_GrSurfaceOrigin, kSkia8888_GrPixelConfig)) return; // Copy video texture to bitmap texture. WebGraphicsContext3D* webGraphicsContext3D = context3D->webContext(); WebCanvas* canvas = context->canvas(); unsigned textureId = static_cast<unsigned>((m_bitmap.getTexture())->getTextureHandle()); if (!m_webMediaPlayer->copyVideoTextureToPlatformTexture(webGraphicsContext3D, textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE, true, false)) return; // Draw the texture based bitmap onto the Canvas. If the canvas is hardware based, this will do a GPU-GPU texture copy. If the canvas is software based, // the texture based bitmap will be readbacked to system memory then draw onto the canvas. SkRect dest; dest.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); SkPaint paint; paint.setAlpha(alpha); // It is not necessary to pass the dest into the drawBitmap call since all the context have been set up before calling paintCurrentFrameInContext. canvas->drawBitmapRect(m_bitmap, NULL, dest, &paint); }
bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DObject texture, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY) { if (!m_data.m_layerBridge || !platformLayer()) return false; Platform3DObject sourceTexture = m_data.m_layerBridge->backBufferTexture(); if (!context.makeContextCurrent()) return false; Extensions3D* extensions = context.getExtensions(); if (!extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy")) return false; // The canvas is stored in a premultiplied format, so unpremultiply if necessary. context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha); // The canvas is stored in an inverted position, so the flip semantics are reversed. context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, !flipY); extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, sourceTexture, texture, 0, internalFormat); context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, false); context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); context.flush(); return true; }
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) { if (!m_context || !m_context->makeContextCurrent() || m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR) return; Extensions3D* extensions = m_context->getExtensions(); #if ENABLE(CANVAS_USES_MAILBOX) // Since the m_frontColorBuffer was produced and sent to the compositor, it cannot be bound to an fbo. // We have to make a copy of it here and bind that copy instead. unsigned sourceTexture = createColorTexture(m_size); extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_frontColorBuffer, sourceTexture, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE); #else // FIXME: Re-examine general correctness of this code beacause m_colorBuffer may contain a stale copy of the data // that was sent to the compositor at some point in the past. unsigned sourceTexture = frontColorBuffer(); #endif // ENABLE(CANVAS_USES_MAILBOX) // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding). // FIXME: The WebGLRenderingContext tracks the current framebuffer binding, it would be slightly more efficient to use this value // rather than querying it off of the context. GC3Dint previousFramebuffer = 0; m_context->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &previousFramebuffer); Platform3DObject framebuffer = m_context->createFramebuffer(); m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer); m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, sourceTexture, 0); extensions->paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_attributes.premultipliedAlpha, imageBuffer); m_context->deleteFramebuffer(framebuffer); #if ENABLE(CANVAS_USES_MAILBOX) m_context->deleteTexture(sourceTexture); #endif // ENABLE(CANVAS_USES_MAILBOX) m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, previousFramebuffer); }
bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase* context) { Extensions3D* extensions = context->graphicsContext3D()->getExtensions(); return extensions->supports("GL_EXT_texture_compression_s3tc") || (extensions->supports("GL_EXT_texture_compression_dxt1") && extensions->supports("GL_CHROMIUM_texture_compression_dxt3") && extensions->supports("GL_CHROMIUM_texture_compression_dxt5")); }
bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox) { if (!m_context || !m_contentsChanged || !m_lastColorBuffer) return false; m_context->makeContextCurrent(); // Resolve the multisampled buffer into the texture referenced by m_lastColorBuffer mailbox. if (multisample()) commit(); // We must restore the texture binding since creating new textures, // consuming and producing mailboxes changes it. ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureUnit, m_texture2DBinding); // First try to recycle an old buffer. RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox(); // No buffer available to recycle, create a new one. if (!nextFrontColorBuffer) { unsigned newColorBuffer = createColorTexture(m_size); // Bad things happened, abandon ship. if (!newColorBuffer) return false; nextFrontColorBuffer = createNewMailbox(newColorBuffer); } if (m_preserveDrawingBuffer == Discard) { m_colorBuffer = nextFrontColorBuffer->textureId; swap(nextFrontColorBuffer, m_lastColorBuffer); // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. // If this stops being true at some point, we should track the current framebuffer binding in the DrawingBuffer and restore // it after attaching the new back buffer here. m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); } else { Extensions3D* extensions = m_context->getExtensions(); extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBuffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE); } if (multisample() && !m_framebufferBinding) bind(); else restoreFramebufferBinding(); m_contentsChanged = false; context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer->textureId); context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer->mailbox.name); context()->flush(); m_context->markLayerComposited(); *outMailbox = nextFrontColorBuffer->mailbox; m_frontColorBuffer = nextFrontColorBuffer->textureId; return true; }
// static bool EXTDrawBuffers::supported(WebGLRenderingContext* context) { #if OS(DARWIN) // https://bugs.webkit.org/show_bug.cgi?id=112486 return false; #endif Extensions3D* extensions = context->graphicsContext3D()->getExtensions(); return extensions->supports("GL_EXT_draw_buffers"); }
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow) : m_currentWidth(0) , m_currentHeight(0) , m_hostWindow(hostWindow) , m_context(BlackBerry::Platform::Graphics::createWebGLContext()) , m_extensions(adoptPtr(new Extensions3DOpenGL(this))) , m_attrs(attrs) , m_texture(0) , m_fbo(0) , m_depthStencilBuffer(0) , m_boundFBO(0) , m_activeTexture(GL_TEXTURE0) , m_boundTexture0(0) , m_multisampleFBO(0) , m_multisampleDepthStencilBuffer(0) , m_multisampleColorBuffer(0) { if (!renderDirectlyToHostWindow) { #if USE(ACCELERATED_COMPOSITING) m_compositingLayer = WebGLLayerWebKitThread::create(); #endif makeContextCurrent(); Extensions3D* extensions = getExtensions(); if (!extensions->supports("GL_IMG_multisampled_render_to_texture")) m_attrs.antialias = false; // Create a texture to render into. ::glGenTextures(1, &m_texture); ::glBindTexture(GL_TEXTURE_2D, m_texture); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ::glBindTexture(GL_TEXTURE_2D, 0); // Create an FBO. ::glGenFramebuffers(1, &m_fbo); ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); if (m_attrs.stencil || m_attrs.depth) ::glGenRenderbuffers(1, &m_depthStencilBuffer); m_boundFBO = m_fbo; #if USE(ACCELERATED_COMPOSITING) static_cast<WebGLLayerWebKitThread*>(m_compositingLayer.get())->setWebGLContext(this); #endif } // FIXME: If GraphicsContext3D is created with renderDirectlyToHostWindow == true, // makeContextCurrent() will make the shared context current. makeContextCurrent(); // FIXME: Do we need to enable GL_VERTEX_PROGRAM_POINT_SIZE with GL ES2? See PR #120141. ::glClearColor(0, 0, 0, 0); }
bool WebMediaPlayerClientImpl::copyVideoTextureToPlatformTexture(WebCore::GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY) { if (!context || !m_webMediaPlayer) return false; Extensions3D* extensions = context->getExtensions(); if (!extensions || !extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy") || !context->makeContextCurrent()) return false; WebGraphicsContext3D* webGraphicsContext3D = GraphicsContext3DPrivate::extractWebGraphicsContext3D(context); return m_webMediaPlayer->copyVideoTextureToPlatformTexture(webGraphicsContext3D, texture, level, internalFormat, premultiplyAlpha, flipY); }
void GraphicsContext3D::validateAttributes() { validateDepthStencil("GL_OES_packed_depth_stencil"); if (m_attrs.antialias) { Extensions3D* extensions = getExtensions(); if (!extensions->supports("GL_IMG_multisampled_render_to_texture")) m_attrs.antialias = false; } }
bool LayerTextureUpdaterSkPicture::createFrameBuffer() { ASSERT(!m_fbo); ASSERT(!m_bufferSize.isEmpty()); // SKIA only needs color and stencil buffers, not depth buffer. // But it is very uncommon for cards to support color + stencil FBO config. // The most common config is color + packed-depth-stencil. // Instead of iterating through all possible FBO configs, we only try the // most common one here. // FIXME: Delegate the task of creating frame-buffer to SKIA. // It has all necessary code to iterate through all possible configs // and choose the one most suitable for its purposes. Extensions3D* extensions = context()->getExtensions(); if (!extensions->supports("GL_OES_packed_depth_stencil")) return false; extensions->ensureEnabled("GL_OES_packed_depth_stencil"); // Create and bind a frame-buffer-object. m_fbo = context()->createFramebuffer(); if (!m_fbo) return false; context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); // We just need to create a stencil buffer for FBO. // The color buffer (texture) will be provided by tiles. // SKIA does not need depth buffer. m_depthStencilBuffer = context()->createRenderbuffer(); if (!m_depthStencilBuffer) { deleteFrameBuffer(); return false; } context()->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); context()->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, Extensions3D::DEPTH24_STENCIL8, m_bufferSize.width(), m_bufferSize.height()); context()->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); context()->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); // Create a skia gpu canvas. GrContext* skiaContext = m_context->grContext(); GrPlatformSurfaceDesc targetDesc; targetDesc.reset(); targetDesc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType; targetDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit; targetDesc.fWidth = m_bufferSize.width(); targetDesc.fHeight = m_bufferSize.height(); targetDesc.fConfig = kRGBA_8888_GrPixelConfig; targetDesc.fStencilBits = 8; targetDesc.fPlatformRenderTarget = m_fbo; SkAutoTUnref<GrRenderTarget> target(static_cast<GrRenderTarget*>(skiaContext->createPlatformSurface(targetDesc))); SkAutoTUnref<SkDevice> device(new SkGpuDevice(skiaContext, target.get())); m_canvas = adoptPtr(new SkCanvas(device.get())); context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0); return true; }
GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject) { if (!arrayObject || m_context->isContextLost()) return 0; if (!arrayObject->hasEverBeenBound()) return 0; Extensions3D* extensions = m_context->graphicsContext3D()->getExtensions(); return extensions->isVertexArrayOES(arrayObject->object()); }
WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ctx, VAOType type) : WebGLVertexArrayObjectBase(ctx, type) { Extensions3D* extensions = context()->graphicsContext3D()->getExtensions(); switch (m_type) { case VAOTypeDefault: break; default: setObject(extensions->createVertexArrayOES()); break; } }
bool WebGLDepthTexture::supported(WebGLRenderingContext* context) { Extensions3D* extensions = context->graphicsContext3D()->extensions(); // Emulating the UNSIGNED_INT_24_8_WEBGL texture internal format in terms // of two separate texture objects is too difficult, so disable depth // textures unless a packed depth/stencil format is available. if (!extensions->supports("GL_OES_packed_depth_stencil")) return false; return extensions->supports("GL_CHROMIUM_depth_texture") || extensions->supports("GL_OES_depth_texture") || extensions->supports("GL_ARB_depth_texture"); }
bool FECustomFilter::createMultisampleBuffer() { ASSERT(!m_triedMultisampleBuffer); m_triedMultisampleBuffer = true; Extensions3D* extensions = m_context->getExtensions(); if (!extensions || !extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || !extensions->supports("GL_ANGLE_framebuffer_blit") || !extensions->supports("GL_OES_rgb8_rgba8")) return false; extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); extensions->ensureEnabled("GL_OES_rgb8_rgba8"); if (!m_multisampleFrameBuffer) m_multisampleFrameBuffer = m_context->createFramebuffer(); if (!m_multisampleRenderBuffer) m_multisampleRenderBuffer = m_context->createRenderbuffer(); if (!m_multisampleDepthBuffer) m_multisampleDepthBuffer = m_context->createRenderbuffer(); return true; }
WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type) : WebGLContextObject(ctx) , m_type(type) , m_hasEverBeenBound(false) , m_boundElementArrayBuffer(0) { m_vertexAttribState.resize(ctx->getMaxVertexAttribs()); Extensions3D* extensions = context()->graphicsContext3D()->getExtensions(); switch (m_type) { case VaoTypeDefault: break; default: setObject(extensions->createVertexArrayOES()); break; } }
SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SolidFillShader> solidFillShader, PassOwnPtr<TexShader> texShader, PassOwnPtr<BicubicShader> bicubicShader, PassOwnArrayPtr<OwnPtr<ConvolutionShader> > convolutionShaders, CreationFlags flags) : m_context(context) , m_bgraSupported(false) , m_quadVertices(0) , m_solidFillShader(solidFillShader) , m_texShader(texShader) , m_bicubicShader(bicubicShader) , m_convolutionShaders(convolutionShaders) , m_oesStandardDerivativesSupported(false) , m_flags(flags) #if USE(SKIA) , m_grContext(0) #endif { allContexts()->add(this); Extensions3D* extensions = m_context->getExtensions(); m_bgraSupported = extensions->supports("GL_EXT_texture_format_BGRA8888") && extensions->supports("GL_EXT_read_format_bgra"); if (m_bgraSupported) { extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888"); extensions->ensureEnabled("GL_EXT_read_format_bgra"); } m_oesStandardDerivativesSupported = extensions->supports("GL_OES_standard_derivatives"); if (m_oesStandardDerivativesSupported) extensions->ensureEnabled("GL_OES_standard_derivatives"); }
PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, AlphaRequirement alpha) { Extensions3D* extensions = context->getExtensions(); bool multisampleSupported = extensions->maySupportMultisampling() && extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample") && extensions->supports("GL_OES_rgb8_rgba8"); if (multisampleSupported) { extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); extensions->ensureEnabled("GL_OES_rgb8_rgba8"); } bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth_stencil"); if (packedDepthStencilSupported) extensions->ensureEnabled("GL_OES_packed_depth_stencil"); RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported, preserve, alpha)); return (drawingBuffer->m_context) ? drawingBuffer.release() : 0; }
void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object) { Extensions3D* extensions = context3d->getExtensions(); switch (m_type) { case VAOTypeDefault: break; default: extensions->deleteVertexArrayOES(object); break; } if (m_boundElementArrayBuffer) m_boundElementArrayBuffer->onDetached(context3d); for (auto& state : m_vertexAttribState) { if (state.bufferBinding) state.bufferBinding->onDetached(context3d); } }
void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject) { if (isLost()) return; if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) { m_context->graphicsContext3D()->synthesizeGLError(GL_INVALID_OPERATION); return; } Extensions3D* extensions = m_context->graphicsContext3D()->extensions(); if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) { extensions->bindVertexArrayOES(arrayObject->object()); arrayObject->setHasEverBeenBound(); m_context->setBoundVertexArrayObject(arrayObject); } else { extensions->bindVertexArrayOES(0); m_context->setBoundVertexArrayObject(0); } }
PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManager> contextEvictionManager) { Extensions3D* extensions = context->getExtensions(); bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample") && extensions->supports("GL_OES_rgb8_rgba8"); if (multisampleSupported) { extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); extensions->ensureEnabled("GL_OES_rgb8_rgba8"); } bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth_stencil"); if (packedDepthStencilSupported) extensions->ensureEnabled("GL_OES_packed_depth_stencil"); RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManager)); return drawingBuffer.release(); }
bool FECustomFilter::resizeMultisampleBuffers(const IntSize& newContextSize) { if (!m_triedMultisampleBuffer && !createMultisampleBuffer()) return false; if (!canUseMultisampleBuffers()) return false; static const int kMaxSampleCount = 4; int maxSupportedSampleCount = 0; m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSupportedSampleCount); int sampleCount = std::min(kMaxSampleCount, maxSupportedSampleCount); if (!sampleCount) { deleteMultisampleRenderBuffers(); return false; } Extensions3D* extensions = m_context->getExtensions(); ASSERT(extensions); m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFrameBuffer); m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleRenderBuffer); extensions->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, Extensions3D::RGBA8_OES, newContextSize.width(), newContextSize.height()); m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, m_multisampleRenderBuffer); m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleDepthBuffer); extensions->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::DEPTH_COMPONENT16, newContextSize.width(), newContextSize.height()); m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_multisampleDepthBuffer); m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) { deleteMultisampleRenderBuffers(); return false; } return true; }
bool GraphicsContext3D::reshapeFBOs(const IntSize& size) { // A BlackBerry-specific implementation of reshapeFBOs is necessary because it contains: // - an Imagination-specific implementation of anti-aliasing // - an Imagination-specific fix for FBOs of size less than (16,16) int fboWidth = size.width(); int fboHeight = size.height(); // Imagination-specific fix if (m_isImaginationHardware) { fboWidth = std::max(fboWidth, 16); fboHeight = std::max(fboHeight, 16); } GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; if (m_attrs.alpha) { internalColorFormat = GL_RGBA; colorFormat = GL_RGBA; } else { internalColorFormat = GL_RGB; colorFormat = GL_RGB; } if (m_attrs.stencil || m_attrs.depth) { // We don't allow the logic where stencil is required and depth is not. // See GraphicsContext3D constructor. if (m_attrs.stencil && m_attrs.depth) internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; else internalDepthStencilFormat = GL_DEPTH_COMPONENT16; } GLint sampleCount = 8; if (m_attrs.antialias) { GLint maxSampleCount; // Hardcode the maximum number of samples due to header issue (PR132183) // ::glGetIntegerv(GL_MAX_SAMPLES_IMG, &maxSampleCount); maxSampleCount = 4; sampleCount = std::min(8, maxSampleCount); } bool mustRestoreFBO = false; if (m_state.boundFBO != m_fbo) { mustRestoreFBO = true; ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); } ::glBindTexture(GL_TEXTURE_2D, m_texture); ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, fboWidth, fboHeight, 0, colorFormat, GL_UNSIGNED_BYTE, 0); Extensions3D* extensions = getExtensions(); if (m_attrs.antialias) { extensions->framebufferTexture2DMultisampleIMG(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0, sampleCount); if (m_attrs.stencil || m_attrs.depth) { ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); extensions->renderbufferStorageMultisampleIMG(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, fboWidth, fboHeight); if (m_attrs.stencil) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); if (m_attrs.depth) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } } else { ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); if (m_attrs.stencil || m_attrs.depth) { ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, fboWidth, fboHeight); if (m_attrs.stencil) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); if (m_attrs.depth) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } } ::glBindTexture(GL_TEXTURE_2D, 0); logFrameBufferStatus(__LINE__); return mustRestoreFBO; }
bool ANGLEInstancedArrays::supported(WebGLRenderingContext* context) { Extensions3D* extensions = context->graphicsContext3D()->extensions(); return extensions->supports("GL_ANGLE_instanced_arrays"); }
bool WebGLDrawBuffers::supported(WebGLRenderingContextBase* context) { Extensions3D* extensions = context->graphicsContext3D()->getExtensions(); return extensions->supports("GL_EXT_draw_buffers") && satisfiesWebGLRequirements(context); }
bool OESTextureFloatLinear::supported(WebGLRenderingContext* context) { Extensions3D* extensions = context->graphicsContext3D()->extensions(); return extensions->supports("GL_OES_texture_float_linear"); }
bool GraphicsContext3D::reshapeFBOs(const IntSize& size) { const int width = size.width(); const int height = size.height(); GLuint colorFormat, internalDepthStencilFormat = 0; if (m_attrs.alpha) { m_internalColorFormat = GL_RGBA8; colorFormat = GL_RGBA; } else { m_internalColorFormat = GL_RGB8; colorFormat = GL_RGB; } if (m_attrs.stencil || m_attrs.depth) { // We don't allow the logic where stencil is required and depth is not. // See GraphicsContext3D::validateAttributes. Extensions3D* extensions = getExtensions(); // Use a 24 bit depth buffer where we know we have it. if (extensions->supports("GL_EXT_packed_depth_stencil")) internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; else internalDepthStencilFormat = GL_DEPTH_COMPONENT; } bool mustRestoreFBO = false; // Resize multisample FBO. if (m_attrs.antialias) { GLint maxSampleCount; ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); GLint sampleCount = std::min(8, maxSampleCount); if (sampleCount > maxSampleCount) sampleCount = maxSampleCount; if (m_state.boundFBO != m_multisampleFBO) { ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); mustRestoreFBO = true; } ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, m_internalColorFormat, width, height); ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); if (m_attrs.stencil || m_attrs.depth) { ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); if (m_attrs.stencil) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); if (m_attrs.depth) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); } ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { // FIXME: cleanup. notImplemented(); } } // resize regular FBO if (m_state.boundFBO != m_fbo) { mustRestoreFBO = true; ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } ::glBindTexture(GL_TEXTURE_2D, m_texture); ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture); ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); ::glBindTexture(GL_TEXTURE_2D, 0); if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) { ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); if (m_attrs.stencil) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); if (m_attrs.depth) ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { // FIXME: cleanup notImplemented(); } if (m_attrs.antialias) { ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); if (m_state.boundFBO == m_multisampleFBO) mustRestoreFBO = false; } return mustRestoreFBO; }