static void RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager, const nsIntPoint& aOffset) { if (aManager->CompositingDisabled()) { return; } aManager->MakeCurrent(); // XXX we might be able to improve performance by using glClear /* Multiply color by the layer opacity, as the shader * ignores layer opacity and expects a final color to * write to the color buffer. This saves a needless * multiply in the fragment shader. */ gfxRGBA color(aLayer->GetColor()); float opacity = aLayer->GetEffectiveOpacity() * color.a; color.r *= opacity; color.g *= opacity; color.b *= opacity; color.a = opacity; ShaderProgramOGL *program = aManager->GetProgram(ColorLayerProgramType, aLayer->GetMaskLayer()); program->Activate(); program->SetLayerQuadRect(aLayer->GetBounds()); program->SetLayerTransform(aLayer->GetEffectiveTransform()); program->SetTextureTransform(gfx3DMatrix()); program->SetRenderOffset(aOffset); program->SetRenderColor(color); program->LoadMask(aLayer->GetMaskLayer()); aManager->BindAndDrawQuad(program); }
void CanvasLayerOGL::RenderLayer(int aPreviousDestination, const nsIntPoint& aOffset) { FirePreTransactionCallback(); UpdateSurface(); if (mOGLManager->CompositingDisabled()) { return; } FireDidTransactionCallback(); mOGLManager->MakeCurrent(); // XXX We're going to need a different program depending on if // mGLBufferIsPremultiplied is TRUE or not. The RGBLayerProgram // assumes that it's true. gl()->fActiveTexture(LOCAL_GL_TEXTURE0); if (mTexture) { gl()->fBindTexture(mTextureTarget, mTexture); } ShaderProgramOGL *program = nullptr; nsIntRect drawRect = mBounds; if (mDelayedUpdates) { NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload"); drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds()); gfx::SurfaceFormat format = gl()->UploadSurfaceToTexture(mCanvasSurface, nsIntRect(0, 0, drawRect.width, drawRect.height), mUploadTexture, true, drawRect.TopLeft()); mLayerProgram = ShaderProgramFromSurfaceFormat(format); mTexture = mUploadTexture; } if (!program) { program = mOGLManager->GetProgram(mLayerProgram, GetMaskLayer()); } #if defined(GL_PROVIDER_GLX) if (mPixmap && !mDelayedUpdates) { sDefGLXLib.BindTexImage(mPixmap); } #endif gl()->ApplyFilterToBoundTexture(mFilter); program->Activate(); if (mLayerProgram == RGBARectLayerProgramType || mLayerProgram == RGBXRectLayerProgramType) { // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1. program->SetTexCoordMultiplier(mBounds.width, mBounds.height); } program->SetLayerQuadRect(drawRect); program->SetLayerTransform(GetEffectiveTransform()); program->SetTextureTransform(gfx3DMatrix()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); if (gl()->CanUploadNonPowerOfTwo()) { mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false); } else { mOGLManager->BindAndDrawQuadWithTextureRect(program, drawRect, drawRect.Size()); } #if defined(GL_PROVIDER_GLX) if (mPixmap && !mDelayedUpdates) { sDefGLXLib.ReleaseTexImage(mPixmap); } #endif }
void ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { if (mOGLManager->CompositingDisabled()) { return; } mOGLManager->MakeCurrent(); if (mImageContainerID) { ImageContainerParent::SetCompositorIDForImage(mImageContainerID, mOGLManager->GetCompositorID()); uint32_t imgVersion = ImageContainerParent::GetSharedImageVersion(mImageContainerID); SharedImage* img = ImageContainerParent::GetSharedImage(mImageContainerID); if (imgVersion != mImageVersion) { if (img && (img->type() == SharedImage::TYUVImage)) { UploadSharedYUVToTexture(img->get_YUVImage()); mImageVersion = imgVersion; } else if (img && (img->type() == SharedImage::TYCbCrImage)) { ShmemYCbCrImage shmemImage(img->get_YCbCrImage().data(), img->get_YCbCrImage().offset()); UploadSharedYCbCrToTexture(shmemImage, img->get_YCbCrImage().picture()); mImageVersion = imgVersion; } else if (img && (img->type() == SharedImage::TRGBImage)) { UploadSharedRGBToTexture(&img->get_RGBImage().data(), img->get_RGBImage().picture(), img->get_RGBImage().rgbFormat()); mImageVersion = imgVersion; } } #ifdef MOZ_WIDGET_GONK if (img && (img->type() == SharedImage::TSurfaceDescriptor) && (img->get_SurfaceDescriptor().type() == SurfaceDescriptor::TSurfaceDescriptorGralloc)) { const SurfaceDescriptorGralloc& desc = img->get_SurfaceDescriptor().get_SurfaceDescriptorGralloc(); sp<GraphicBuffer> graphicBuffer = GrallocBufferActor::GetFrom(desc); mSize = gfxIntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight()); if (!mExternalBufferTexture.IsAllocated()) { mExternalBufferTexture.Allocate(gl()); } gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->BindExternalBuffer(mExternalBufferTexture.GetTextureID(), graphicBuffer->getNativeBuffer()); mImageVersion = imgVersion; } #endif } if (mTexImage) { NS_ASSERTION(mTexImage->GetContentType() != gfxASurface::CONTENT_ALPHA, "Image layer has alpha image"); ShaderProgramOGL *colorProgram = mOGLManager->GetProgram(mTexImage->GetShaderProgramType(), GetMaskLayer()); colorProgram->Activate(); colorProgram->SetTextureUnit(0); colorProgram->SetLayerTransform(GetEffectiveTransform()); colorProgram->SetLayerOpacity(GetEffectiveOpacity()); colorProgram->SetRenderOffset(aOffset); colorProgram->LoadMask(GetMaskLayer()); mTexImage->SetFilter(mFilter); mTexImage->BeginTileIteration(); if (gl()->CanUploadNonPowerOfTwo()) { do { nsIntRect rect = mTexImage->GetTileRect(); if (!rect.IsEmpty()) { TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); colorProgram->SetLayerQuadRect(rect); mOGLManager->BindAndDrawQuad(colorProgram); } } while (mTexImage->NextTile()); } else { do { nsIntRect rect = mTexImage->GetTileRect(); if (!rect.IsEmpty()) { TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); colorProgram->SetLayerQuadRect(rect); // We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f // in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture mOGLManager->BindAndDrawQuadWithTextureRect(colorProgram, nsIntRect(0, 0, mTexImage->GetTileRect().width, mTexImage->GetTileRect().height), mTexImage->GetTileRect().Size()); } } while (mTexImage->NextTile()); } #ifdef MOZ_WIDGET_GONK } else if (mExternalBufferTexture.IsAllocated()) { gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, mExternalBufferTexture.GetTextureID()); ShaderProgramOGL *program = mOGLManager->GetProgram(RGBAExternalLayerProgramType, GetMaskLayer()); gl()->ApplyFilterToBoundTexture(LOCAL_GL_TEXTURE_EXTERNAL, mFilter); program->Activate(); program->SetLayerQuadRect(nsIntRect(0, 0, mSize.width, mSize.height)); program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuad(program); // Make sure that we release the underlying external image gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, 0); mExternalBufferTexture.Release(); #endif } else if (mSharedHandle) { GLContext::SharedHandleDetails handleDetails; if (!gl()->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) { NS_ERROR("Failed to get shared handle details"); return; } ShaderProgramOGL* program = mOGLManager->GetProgram(handleDetails.mProgramType, GetMaskLayer()); program->Activate(); program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->SetTextureTransform(handleDetails.mTextureTransform); program->LoadMask(GetMaskLayer()); MakeTextureIfNeeded(gl(), mTexture); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(handleDetails.mTarget, mTexture); if (!gl()->AttachSharedHandle(mShareType, mSharedHandle)) { NS_ERROR("Failed to bind shared texture handle"); return; } gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA, LOCAL_GL_ONE, LOCAL_GL_ONE); gl()->ApplyFilterToBoundTexture(mFilter); program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mSize)); mOGLManager->BindAndDrawQuad(program, mInverted); gl()->fBindTexture(handleDetails.mTarget, 0); gl()->DetachSharedHandle(mShareType, mSharedHandle); } else if (mRGBTexture.IsAllocated()) { gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mRGBTexture.GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); ShaderProgramOGL *shader = mOGLManager->GetProgram(RGBALayerProgramType, GetMaskLayer()); shader->Activate(); shader->SetLayerQuadRect(nsIntRect(0, 0, mPictureRect.width, mPictureRect.height)); shader->SetTextureUnit(0); shader->SetLayerTransform(GetEffectiveTransform()); shader->SetLayerOpacity(GetEffectiveOpacity()); shader->SetRenderOffset(aOffset); shader->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuadWithTextureRect(shader, mPictureRect, nsIntSize(mSize.width, mSize.height)); } else { gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); gl()->fActiveTexture(LOCAL_GL_TEXTURE1); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[1].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); gl()->fActiveTexture(LOCAL_GL_TEXTURE2); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[2].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); ShaderProgramOGL *yuvProgram = mOGLManager->GetProgram(YCbCrLayerProgramType, GetMaskLayer()); yuvProgram->Activate(); yuvProgram->SetLayerQuadRect(nsIntRect(0, 0, mPictureRect.width, mPictureRect.height)); yuvProgram->SetYCbCrTextureUnits(0, 1, 2); yuvProgram->SetLayerTransform(GetEffectiveTransform()); yuvProgram->SetLayerOpacity(GetEffectiveOpacity()); yuvProgram->SetRenderOffset(aOffset); yuvProgram->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuadWithTextureRect(yuvProgram, mPictureRect, nsIntSize(mSize.width, mSize.height)); } }
void ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { /** * Setup our temporary texture for rendering the contents of this container. */ GLuint containerSurface; GLuint frameBuffer; nsIntPoint childOffset(aOffset); nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); nsIntRect cachedScissor = gl()->ScissorRect(); gl()->PushScissorRect(); mSupportsComponentAlphaChildren = false; float opacity = GetEffectiveOpacity(); const gfx3DMatrix& transform = GetEffectiveTransform(); bool needsFramebuffer = UseIntermediateSurface(); if (needsFramebuffer) { nsIntRect framebufferRect = visibleRect; // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. GLint maxTexSize; gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); framebufferRect.width = std::min(framebufferRect.width, maxTexSize); framebufferRect.height = std::min(framebufferRect.height, maxTexSize); LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; if (GetEffectiveVisibleRegion().GetNumRects() == 1 && (GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff mSupportsComponentAlphaChildren = true; mode = LayerManagerOGL::InitModeNone; } else { const gfx3DMatrix& transform3D = GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(this) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { mode = gfxPlatform::ComponentAlphaEnabled() ? LayerManagerOGL::InitModeCopy : LayerManagerOGL::InitModeClear; framebufferRect.x += transform.x0; framebufferRect.y += transform.y0; mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); } } gl()->PushViewportRect(); framebufferRect -= childOffset; if (!mOGLManager->CompositingDisabled()) { if (!mOGLManager->CreateFBOWithTexture(framebufferRect, mode, aPreviousFrameBuffer, &frameBuffer, &containerSurface)) { gl()->PopViewportRect(); gl()->PopScissorRect(); gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); return; } } childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; } else { frameBuffer = aPreviousFrameBuffer; mSupportsComponentAlphaChildren = (GetContentFlags() & Layer::CONTENT_OPAQUE) || (GetParent() && GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerOGL* layerToRender = static_cast<LayerOGL*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { continue; } nsIntRect scissorRect = layerToRender->GetLayer()-> CalculateScissorRect(cachedScissor, &mOGLManager->GetWorldTransform()); if (scissorRect.IsEmpty()) { continue; } gl()->fScissor(scissorRect.x, scissorRect.y, scissorRect.width, scissorRect.height); layerToRender->RenderLayer(frameBuffer, childOffset); gl()->MakeCurrent(); } if (needsFramebuffer) { // Unbind the current framebuffer and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { nsRefPtr<gfxImageSurface> surf = gl()->GetTexImage(containerSurface, true, mOGLManager->GetFBOTextureFormat()); WriteSnapshotToDumpFile(this, surf); } #endif // Restore the viewport gl()->PopViewportRect(); nsIntRect viewport = gl()->ViewportRect(); mOGLManager->SetupPipeline(viewport.width, viewport.height, LayerManagerOGL::ApplyWorldTransform); gl()->PopScissorRect(); if (!mOGLManager->CompositingDisabled()) { gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); gl()->fDeleteFramebuffers(1, &frameBuffer); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(mOGLManager->FBOTextureTarget(), containerSurface); MaskType maskType = MaskNone; if (GetMaskLayer()) { if (!GetTransform().CanDraw2D()) { maskType = Mask3d; } else { maskType = Mask2d; } } ShaderProgramOGL *rgb = mOGLManager->GetFBOLayerProgram(maskType); rgb->Activate(); rgb->SetLayerQuadRect(visibleRect); rgb->SetLayerTransform(transform); rgb->SetTextureTransform(gfx3DMatrix()); rgb->SetLayerOpacity(opacity); rgb->SetRenderOffset(aOffset); rgb->SetTextureUnit(0); rgb->LoadMask(GetMaskLayer()); if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { // 2DRect case, get the multiplier right for a sampler2DRect rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); } // Drawing is always flipped, but when copying between surfaces we want to avoid // this. Pass true for the flip parameter to introduce a second flip // that cancels the other one out. mOGLManager->BindAndDrawQuad(rgb, true); // Clean up resources. This also unbinds the texture. gl()->fDeleteTextures(1, &containerSurface); } } else { gl()->PopScissorRect(); } }
void ImageLayerOGL::RenderLayer(int, const nsIntPoint& aOffset) { nsRefPtr<ImageContainer> container = GetContainer(); if (!container || mOGLManager->CompositingDisabled()) return; mOGLManager->MakeCurrent(); AutoLockImage autoLock(container); Image *image = autoLock.GetImage(); if (!image) { return; } NS_ASSERTION(image->GetFormat() != REMOTE_IMAGE_BITMAP, "Remote images aren't handled yet in OGL layers!"); if (image->GetFormat() == PLANAR_YCBCR) { PlanarYCbCrImage *yuvImage = static_cast<PlanarYCbCrImage*>(image); if (!yuvImage->IsValid()) { return; } PlanarYCbCrOGLBackendData *data = static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LAYERS_OPENGL)); if (data && data->mTextures->GetGLContext() != gl()) { // If these textures were allocated by another layer manager, // clear them out and re-allocate below. data = nullptr; yuvImage->SetBackendData(LAYERS_OPENGL, nullptr); } if (!data) { AllocateTexturesYCbCr(yuvImage); data = static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LAYERS_OPENGL)); } if (!data || data->mTextures->GetGLContext() != gl()) { // XXX - Can this ever happen? If so I need to fix this! return; } gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE2); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[2].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); gl()->fActiveTexture(LOCAL_GL_TEXTURE1); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[1].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[0].GetTextureID()); gl()->ApplyFilterToBoundTexture(mFilter); ShaderProgramOGL *program = mOGLManager->GetProgram(YCbCrLayerProgramType, GetMaskLayer()); program->Activate(); program->SetLayerQuadRect(nsIntRect(0, 0, yuvImage->GetSize().width, yuvImage->GetSize().height)); program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetYCbCrTextureUnits(0, 1, 2); program->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuadWithTextureRect(program, yuvImage->GetData()->GetPictureRect(), nsIntSize(yuvImage->GetData()->mYSize.width, yuvImage->GetData()->mYSize.height)); // We shouldn't need to do this, but do it anyway just in case // someone else forgets. gl()->fActiveTexture(LOCAL_GL_TEXTURE0); } else if (image->GetFormat() == CAIRO_SURFACE) { CairoImage *cairoImage = static_cast<CairoImage*>(image); if (!cairoImage->mSurface) { return; } NS_ASSERTION(cairoImage->mSurface->GetContentType() != gfxASurface::CONTENT_ALPHA, "Image layer has alpha image"); CairoOGLBackendData *data = static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LAYERS_OPENGL)); if (data && data->mTexture.GetGLContext() != gl()) { // If this texture was allocated by another layer manager, clear // it out and re-allocate below. data = nullptr; cairoImage->SetBackendData(LAYERS_OPENGL, nullptr); } if (!data) { AllocateTexturesCairo(cairoImage); data = static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LAYERS_OPENGL)); } if (!data || data->mTexture.GetGLContext() != gl()) { // XXX - Can this ever happen? If so I need to fix this! return; } gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTexture.GetTextureID()); ShaderProgramOGL *program = mOGLManager->GetProgram(data->mLayerProgram, GetMaskLayer()); gl()->ApplyFilterToBoundTexture(mFilter); program->Activate(); program->SetLayerQuadRect(nsIntRect(0, 0, cairoImage->GetSize().width, cairoImage->GetSize().height)); program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuad(program); } else if (image->GetFormat() == SHARED_TEXTURE) { SharedTextureImage* texImage = static_cast<SharedTextureImage*>(image); const SharedTextureImage::Data* data = texImage->GetData(); GLContext::SharedHandleDetails handleDetails; if (!gl()->GetSharedHandleDetails(data->mShareType, data->mHandle, handleDetails)) { NS_ERROR("Failed to get shared handle details"); return; } ShaderProgramOGL* program = mOGLManager->GetProgram(handleDetails.mProgramType, GetMaskLayer()); program->Activate(); if (handleDetails.mProgramType == gl::RGBARectLayerProgramType) { // 2DRect case, get the multiplier right for a sampler2DRect program->SetTexCoordMultiplier(data->mSize.width, data->mSize.height); } program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->SetTextureTransform(handleDetails.mTextureTransform); program->LoadMask(GetMaskLayer()); if (!texImage->GetBackendData(LAYERS_OPENGL)) { AllocateTextureSharedTexture(texImage, gl(), handleDetails.mTarget); } ImageOGLBackendData *backendData = static_cast<ImageOGLBackendData*>(texImage->GetBackendData(LAYERS_OPENGL)); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->fBindTexture(handleDetails.mTarget, backendData->mTexture.GetTextureID()); if (!gl()->AttachSharedHandle(data->mShareType, data->mHandle)) { NS_ERROR("Failed to bind shared texture handle"); return; } gl()->ApplyFilterToBoundTexture(handleDetails.mTarget, mFilter); program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), data->mSize)); mOGLManager->BindAndDrawQuad(program, data->mInverted); gl()->fBindTexture(handleDetails.mTarget, 0); gl()->DetachSharedHandle(data->mShareType, data->mHandle); #ifdef MOZ_WIDGET_GONK } else if (image->GetFormat() == GONK_IO_SURFACE) { GonkIOSurfaceImage *ioImage = static_cast<GonkIOSurfaceImage*>(image); if (!ioImage) { return; } gl()->MakeCurrent(); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); if (!ioImage->GetBackendData(LAYERS_OPENGL)) { AllocateTextureIOSurface(ioImage, gl()); } GonkIOSurfaceImageOGLBackendData *data = static_cast<GonkIOSurfaceImageOGLBackendData*>(ioImage->GetBackendData(LAYERS_OPENGL)); gl()->fActiveTexture(LOCAL_GL_TEXTURE0); gl()->BindExternalBuffer(data->mTexture.GetTextureID(), ioImage->GetNativeBuffer()); ShaderProgramOGL *program = mOGLManager->GetProgram(RGBAExternalLayerProgramType, GetMaskLayer()); gl()->ApplyFilterToBoundTexture(mFilter); program->Activate(); program->SetLayerQuadRect(nsIntRect(0, 0, ioImage->GetSize().width, ioImage->GetSize().height)); program->SetLayerTransform(GetEffectiveTransform()); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); mOGLManager->BindAndDrawQuadWithTextureRect(program, GetVisibleRegion().GetBounds(), nsIntSize(ioImage->GetSize().width, ioImage->GetSize().height)); #endif } GetContainer()->NotifyPaintedImage(image); }