void ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { if (!mTexImage && !IsValidSharedTexDescriptor(mFrontBufferDescriptor) && !IsValidSurfaceStreamDescriptor(mFrontBufferDescriptor)) { return; } if (mOGLManager->CompositingDisabled()) { return; } mOGLManager->MakeCurrent(); gl()->EmptyTexGarbageBin(); //ScopedBindTexture autoTex(gl()); gfx3DMatrix effectiveTransform = GetEffectiveTransform(); gfxPattern::GraphicsFilter filter = mFilter; #ifdef ANDROID // Bug 691354 // Using the LINEAR filter we get unexplained artifacts. // Use NEAREST when no scaling is required. gfxMatrix matrix; bool is2D = GetEffectiveTransform().Is2D(&matrix); if (is2D && !matrix.HasNonTranslationOrFlip()) { filter = gfxPattern::FILTER_NEAREST; } #endif SurfaceStream* surfStream = nullptr; SharedSurface* sharedSurf = nullptr; if (IsValidSurfaceStreamDescriptor(mFrontBufferDescriptor)) { const SurfaceStreamDescriptor& streamDesc = mFrontBufferDescriptor.get_SurfaceStreamDescriptor(); surfStream = SurfaceStream::FromHandle(streamDesc.handle()); MOZ_ASSERT(surfStream); sharedSurf = surfStream->SwapConsumer(); if (!sharedSurf) { // We don't have a valid surf to show yet. return; } gfxImageSurface* toUpload = nullptr; switch (sharedSurf->Type()) { case SharedSurfaceType::GLTextureShare: { mCurTexture = SharedSurface_GLTexture::Cast(sharedSurf)->Texture(); MOZ_ASSERT(mCurTexture); mShaderType = sharedSurf->HasAlpha() ? RGBALayerProgramType : RGBXLayerProgramType; break; } case SharedSurfaceType::EGLImageShare: { SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); mCurTexture = eglImageSurf->AcquireConsumerTexture(gl()); if (!mCurTexture) { toUpload = eglImageSurf->GetPixels(); MOZ_ASSERT(toUpload); } else { mShaderType = sharedSurf->HasAlpha() ? RGBALayerProgramType : RGBXLayerProgramType; } break; } case SharedSurfaceType::Basic: { toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); MOZ_ASSERT(toUpload); break; } default: MOZ_NOT_REACHED("Invalid SharedSurface type."); return; } if (toUpload) { // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? nsIntSize size(toUpload->GetSize()); nsIntRect rect(nsIntPoint(0,0), size); nsIntRegion bounds(rect); mShaderType = gl()->UploadSurfaceToTexture(toUpload, bounds, mUploadTexture, true); mCurTexture = mUploadTexture; } MOZ_ASSERT(mCurTexture); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mCurTexture); gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); } else if (mTexImage) { mShaderType = mTexImage->GetShaderProgramType(); } else { MOZ_NOT_REACHED("What can we do?"); return; } ShaderProgramOGL* program = mOGLManager->GetProgram(mShaderType, GetMaskLayer()); program->Activate(); program->SetLayerTransform(effectiveTransform); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); if (surfStream) { MOZ_ASSERT(sharedSurf); gl()->ApplyFilterToBoundTexture(filter); program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), sharedSurf->Size())); mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, 0); } else { // Tiled texture image rendering path mTexImage->SetFilter(filter); mTexImage->BeginTileIteration(); if (gl()->CanUploadNonPowerOfTwo()) { do { TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); program->SetLayerQuadRect(mTexImage->GetTileRect()); mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles? } while (mTexImage->NextTile()); } else { do { TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); program->SetLayerQuadRect(mTexImage->GetTileRect()); // 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 // We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the // actual texture, even though its origin in the composed (tiled) texture is not 0,0 // FIXME: we need to handle mNeedsYFlip, Bug #728625 mOGLManager->BindAndDrawQuadWithTextureRect(program, nsIntRect(0, 0, mTexImage->GetTileRect().width, mTexImage->GetTileRect().height), mTexImage->GetTileRect().Size(), mTexImage->GetWrapMode(), mNeedsYFlip); } while (mTexImage->NextTile()); } } }
bool SurfaceStreamHostOGL::Lock() { mGL->MakeCurrent(); SharedSurface* sharedSurf = mStream->SwapConsumer(); if (!sharedSurf) { // We don't have a valid surf to show yet. return false; } mGL->MakeCurrent(); mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height); gfxImageSurface* toUpload = nullptr; switch (sharedSurf->Type()) { case SharedSurfaceType::GLTextureShare: { SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf); glTexSurf->SetConsumerGL(mGL); mTextureHandle = glTexSurf->Texture(); mTextureTarget = glTexSurf->TextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8 : FORMAT_R8G8B8X8; break; } case SharedSurfaceType::EGLImageShare: { SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); mTextureHandle = eglImageSurf->AcquireConsumerTexture(mGL); mTextureTarget = eglImageSurf->TextureTarget(); if (!mTextureHandle) { toUpload = eglImageSurf->GetPixels(); MOZ_ASSERT(toUpload); } else { mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8 : FORMAT_R8G8B8X8; } break; } #ifdef XP_MACOSX case SharedSurfaceType::IOSurface: { SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf); mTextureHandle = glTexSurf->Texture(); mTextureTarget = glTexSurf->TextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8 : FORMAT_R8G8B8X8; break; } #endif case SharedSurfaceType::Basic: { toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); MOZ_ASSERT(toUpload); break; } default: MOZ_CRASH("Invalid SharedSurface type."); } if (toUpload) { // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? nsIntSize size(toUpload->GetSize()); nsIntRect rect(nsIntPoint(0,0), size); nsIntRegion bounds(rect); mFormat = mGL->UploadSurfaceToTexture(toUpload, bounds, mUploadTexture, true); mTextureHandle = mUploadTexture; mTextureTarget = LOCAL_GL_TEXTURE_2D; } MOZ_ASSERT(mTextureHandle); mGL->fBindTexture(mTextureTarget, mTextureHandle); mGL->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); mGL->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); return true; }
bool StreamTextureSourceOGL::RetrieveTextureFromStream() { gl()->MakeCurrent(); SharedSurface* sharedSurf = mStream->SwapConsumer(); if (!sharedSurf) { // We don't have a valid surf to show yet. return false; } gl()->MakeCurrent(); mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height); DataSourceSurface* toUpload = nullptr; switch (sharedSurf->Type()) { case SharedSurfaceType::GLTextureShare: { SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf); mTextureHandle = glTexSurf->ConsTexture(gl()); mTextureTarget = glTexSurf->ConsTextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } case SharedSurfaceType::EGLImageShare: { SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } #ifdef XP_MACOSX case SharedSurfaceType::IOSurface: { SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf); mTextureHandle = glTexSurf->ConsTexture(gl()); mTextureTarget = glTexSurf->ConsTextureTarget(); MOZ_ASSERT(mTextureHandle); mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; break; } #endif case SharedSurfaceType::Basic: { toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); MOZ_ASSERT(toUpload); break; } default: MOZ_CRASH("Invalid SharedSurface type."); } if (toUpload) { // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? nsIntSize size(ThebesIntSize(toUpload->GetSize())); nsIntRect rect(nsIntPoint(0,0), size); nsIntRegion bounds(rect); mFormat = UploadSurfaceToTexture(gl(), toUpload, bounds, mUploadTexture, true); mTextureHandle = mUploadTexture; mTextureTarget = LOCAL_GL_TEXTURE_2D; } MOZ_ASSERT(mTextureHandle); gl()->fBindTexture(mTextureTarget, mTextureHandle); gl()->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); gl()->fTexParameteri(mTextureTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); ClearCachedFilter(); return true; }