already_AddRefed<DataSourceSurface> CompositingRenderTargetOGL::Dump(Compositor* aCompositor) { MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); CompositorOGL* compositorOGL = aCompositor->AsCompositorOGL(); return ReadBackSurface(mGL, mTextureHandle, true, compositorOGL->GetFBOFormat()); }
TemporaryRef<DataSourceSurface> CompositingRenderTargetOGL::Dump(Compositor* aCompositor) { MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(aCompositor); return ReadBackSurface(mGL, mTextureHandle, true, compositorOGL->GetFBOFormat()); }
void TiledDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); if (mGL && !glCompositor) { DeleteTextures(); } mGL = glCompositor ? glCompositor->gl() : nullptr; }
void SurfaceStreamHostOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); if (mGL && !glCompositor) { DeleteTextures(); } mGL = glCompositor ? glCompositor->gl() : nullptr; }
void TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); if (!glCompositor || (mGL != glCompositor->gl())) { DeallocateDeviceData(); mGL = glCompositor ? glCompositor->gl() : nullptr; } }
void YCbCrDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); GLContext* newGL = glCompositor ? glCompositor->gl() : nullptr; if (mGL != newGL) { mGL = newGL; mYTexture->mTexImage = nullptr; mCbTexture->mTexImage = nullptr; mCrTexture->mTexImage = nullptr; // if we have a buffer we reupload it with the new gl context if (newGL && mBuffer && mBuffer->type() == SurfaceDescriptor::TYCbCrImage) { UpdateImpl(*mBuffer); } } }
void TextureImageDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); GLContext* newGL = glCompositor ? glCompositor->gl() : nullptr; if (mGL != newGL) { mGL = newGL; mTexture = nullptr; // if we have a buffer we reupload it with the new gl context // Post landing TODO: the new DeprecatedTextureClient/Host model will make this // go away. if (newGL && mBuffer && IsSurfaceDescriptorValid(*mBuffer)) { UpdateImpl(*mBuffer); } } }
bool StreamTextureHost::Lock() { if (!mCompositor) { return false; } gfx::SharedSurface* abstractSurf = mStream->SwapConsumer(); bool compositorSupportsShSurfType = false; switch (mCompositor->GetBackendType()) { case LayersBackend::LAYERS_BASIC: case LayersBackend::LAYERS_D3D9: case LayersBackend::LAYERS_D3D10: switch (abstractSurf->Type()) { case gfx::SharedSurfaceType::Basic: compositorSupportsShSurfType = true; break; default: break; } break; case LayersBackend::LAYERS_OPENGL: switch (abstractSurf->Type()) { case gfx::SharedSurfaceType::Basic: case gfx::SharedSurfaceType::GLTextureShare: case gfx::SharedSurfaceType::EGLImageShare: case gfx::SharedSurfaceType::Gralloc: case gfx::SharedSurfaceType::IOSurface: compositorSupportsShSurfType = true; break; default: break; } break; case LayersBackend::LAYERS_D3D11: switch (abstractSurf->Type()) { case gfx::SharedSurfaceType::Basic: case gfx::SharedSurfaceType::EGLSurfaceANGLE: compositorSupportsShSurfType = true; break; default: break; } break; default: break; } RefPtr<NewTextureSource> newTexSource; if (compositorSupportsShSurfType) { gfx::SurfaceFormat format = abstractSurf->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8; switch (abstractSurf->Type()) { case gfx::SharedSurfaceType::Basic: { gl::SharedSurface_Basic* surf = gl::SharedSurface_Basic::Cast(abstractSurf); if (!this->mDataTextureSource) { TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT; this->mDataTextureSource = mCompositor->CreateDataTextureSource(flags); } this->mDataTextureSource->Update(surf->GetData()); newTexSource = mDataTextureSource; break; } case gfx::SharedSurfaceType::GLTextureShare: { gl::SharedSurface_GLTexture* surf = gl::SharedSurface_GLTexture::Cast(abstractSurf); MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor); gl::GLContext* gl = compositorOGL->gl(); GLenum target = surf->ConsTextureTarget(); GLuint tex = surf->ConsTexture(gl); newTexSource = new GLTextureSource(compositorOGL, tex, format, target, surf->Size()); break; } #ifdef MOZ_ENABLE_D3D10_LAYER case gfx::SharedSurfaceType::EGLSurfaceANGLE: { gl::SharedSurface_ANGLEShareHandle* surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf); HANDLE shareHandle = surf->GetShareHandle(); MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_D3D11); CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(mCompositor); ID3D11Device* d3d = compositorD3D11->GetDevice(); nsRefPtr<ID3D11Texture2D> tex; HRESULT hr = d3d->OpenSharedResource(shareHandle, __uuidof(ID3D11Texture2D), getter_AddRefs(tex)); if (FAILED(hr)) { NS_WARNING("Failed to open shared resource."); break; } newTexSource = new DataTextureSourceD3D11(format, compositorD3D11, tex); break; } #endif case gfx::SharedSurfaceType::EGLImageShare: { gl::SharedSurface_EGLImage* surf = gl::SharedSurface_EGLImage::Cast(abstractSurf); MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor); gl::GLContext* gl = compositorOGL->gl(); MOZ_ASSERT(gl->IsCurrent()); GLenum target = 0; GLuint tex = 0; surf->AcquireConsumerTexture(gl, &tex, &target); newTexSource = new GLTextureSource(compositorOGL, tex, format, target, surf->Size()); break; } case gfx::SharedSurfaceType::Gralloc: { MOZ_ASSERT(false, "WebGL in the Host process? Gralloc without E10S? Not yet supported."); break; } #ifdef XP_MACOSX case gfx::SharedSurfaceType::IOSurface: { gl::SharedSurface_IOSurface* surf = gl::SharedSurface_IOSurface::Cast(abstractSurf); MacIOSurface* ioSurf = surf->GetIOSurface(); MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor); newTexSource = new MacIOSurfaceTextureSourceOGL(compositorOGL, ioSurf); break; } #endif default: break; } } else { // Do readback, and make a buffer view for it? NS_WARNING("`!compositorSupportsShSurfType`."); return false; } MOZ_ASSERT(newTexSource.get(), "TextureSource creation failed."); if (!newTexSource) return false; mTextureSource = newTexSource; return true; }
void LayerManagerComposite::RenderToPresentationSurface() { if (!AndroidBridge::Bridge()) { return; } void* window = AndroidBridge::Bridge()->GetPresentationWindow(); if (!window) { return; } EGLSurface surface = AndroidBridge::Bridge()->GetPresentationSurface(); if (!surface) { //create surface; surface = GLContextProviderEGL::CreateEGLSurface(window); if (!surface) { return; } AndroidBridge::Bridge()->SetPresentationSurface(surface); } CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get()); GLContext* gl = compositor->gl(); GLContextEGL* egl = GLContextEGL::Cast(gl); if (!egl) { return; } const IntSize windowSize = AndroidBridge::Bridge()->GetNativeWindowSize(window); if ((windowSize.width <= 0) || (windowSize.height <= 0)) { return; } const int actualWidth = windowSize.width; const int actualHeight = windowSize.height; const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize(); const int pageWidth = originalSize.width; const int pageHeight = originalSize.height; float scale = 1.0; if ((pageWidth > actualWidth) || (pageHeight > actualHeight)) { const float scaleWidth = (float)actualWidth / (float)pageWidth; const float scaleHeight = (float)actualHeight / (float)pageHeight; scale = scaleWidth <= scaleHeight ? scaleWidth : scaleHeight; } const gfx::IntSize actualSize(actualWidth, actualHeight); ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize); const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0); ScopedCompositorRenderOffset overrideRenderOffset(compositor, offset); ScopedContextSurfaceOverride overrideSurface(egl, surface); nsIntRegion invalid; Rect bounds(0.0f, 0.0f, scale * pageWidth, (float)actualHeight); Rect rect, actualBounds; mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds); // Override the projection matrix since the presentation frame buffer // is probably not the same size as the device frame buffer. The override // projection matrix also scales the content to fit into the presentation // frame buffer. Matrix viewMatrix; viewMatrix.PreTranslate(-1.0, 1.0); viewMatrix.PreScale((2.0f * scale) / (float)actualWidth, (2.0f * scale) / (float)actualHeight); viewMatrix.PreScale(1.0f, -1.0f); viewMatrix.PreTranslate((int)((float)offset.x / scale), offset.y); Matrix4x4 projMatrix = Matrix4x4::From2D(viewMatrix); ScopedCompositorProjMatrix overrideProjMatrix(compositor, projMatrix); // The Java side of Fennec sets a scissor rect that accounts for // chrome such as the URL bar. Override that so that the entire frame buffer // is cleared. ScopedScissorRect screen(egl, 0, 0, actualWidth, actualHeight); egl->fClearColor(0.0, 0.0, 0.0, 0.0); egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT); const IntRect clipRect = IntRect(0, 0, (int)(scale * pageWidth), actualHeight); RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect)); RootLayer()->RenderLayer(clipRect); mCompositor->EndFrame(); mCompositor->SetDispAcquireFence(mRoot); }
void LayerManagerComposite::RenderToPresentationSurface() { #ifdef MOZ_WIDGET_ANDROID nsIWidget* const widget = mCompositor->GetWidget()->RealWidget(); auto window = static_cast<ANativeWindow*>( widget->GetNativeData(NS_PRESENTATION_WINDOW)); if (!window) { return; } EGLSurface surface = widget->GetNativeData(NS_PRESENTATION_SURFACE); if (!surface) { //create surface; surface = GLContextProviderEGL::CreateEGLSurface(window); if (!surface) { return; } widget->SetNativeData(NS_PRESENTATION_SURFACE, reinterpret_cast<uintptr_t>(surface)); } CompositorOGL* compositor = mCompositor->AsCompositorOGL(); GLContext* gl = compositor->gl(); GLContextEGL* egl = GLContextEGL::Cast(gl); if (!egl) { return; } const IntSize windowSize(ANativeWindow_getWidth(window), ANativeWindow_getHeight(window)); #endif if ((windowSize.width <= 0) || (windowSize.height <= 0)) { return; } ScreenRotation rotation = compositor->GetScreenRotation(); const int actualWidth = windowSize.width; const int actualHeight = windowSize.height; const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize(); const nsIntRect originalRect = nsIntRect(0, 0, originalSize.width, originalSize.height); int pageWidth = originalSize.width; int pageHeight = originalSize.height; if (rotation == ROTATION_90 || rotation == ROTATION_270) { pageWidth = originalSize.height; pageHeight = originalSize.width; } float scale = 1.0; if ((pageWidth > actualWidth) || (pageHeight > actualHeight)) { const float scaleWidth = (float)actualWidth / (float)pageWidth; const float scaleHeight = (float)actualHeight / (float)pageHeight; scale = scaleWidth <= scaleHeight ? scaleWidth : scaleHeight; } const gfx::IntSize actualSize(actualWidth, actualHeight); ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize); const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0); ScopedContextSurfaceOverride overrideSurface(egl, surface); Matrix viewMatrix = ComputeTransformForRotation(originalRect, rotation); viewMatrix.Invert(); // unrotate viewMatrix.PostScale(scale, scale); viewMatrix.PostTranslate(offset.x, offset.y); Matrix4x4 matrix = Matrix4x4::From2D(viewMatrix); mRoot->ComputeEffectiveTransforms(matrix); nsIntRegion opaque; LayerIntRegion visible; PostProcessLayers(mRoot, opaque, visible, Nothing()); nsIntRegion invalid; IntRect bounds = IntRect::Truncate(0, 0, scale * pageWidth, actualHeight); IntRect rect, actualBounds; MOZ_ASSERT(mRoot->GetOpacity() == 1); mCompositor->BeginFrame(invalid, nullptr, bounds, nsIntRegion(), &rect, &actualBounds); // The Java side of Fennec sets a scissor rect that accounts for // chrome such as the URL bar. Override that so that the entire frame buffer // is cleared. ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight); egl->fClearColor(0.0, 0.0, 0.0, 0.0); egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT); const IntRect clipRect = IntRect::Truncate(0, 0, actualWidth, actualHeight); RootLayer()->Prepare(RenderTargetIntRect::FromUnknownRect(clipRect)); RootLayer()->RenderLayer(clipRect); mCompositor->EndFrame(); }
void LayerManagerComposite::RenderToPresentationSurface() { #ifdef MOZ_WIDGET_ANDROID if (!AndroidBridge::Bridge()) { return; } void* window = AndroidBridge::Bridge()->GetPresentationWindow(); if (!window) { return; } EGLSurface surface = AndroidBridge::Bridge()->GetPresentationSurface(); if (!surface) { //create surface; surface = GLContextProviderEGL::CreateEGLSurface(window); if (!surface) { return; } AndroidBridge::Bridge()->SetPresentationSurface(surface); } CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get()); GLContext* gl = compositor->gl(); GLContextEGL* egl = GLContextEGL::Cast(gl); if (!egl) { return; } const IntSize windowSize = AndroidBridge::Bridge()->GetNativeWindowSize(window); #elif defined(MOZ_WIDGET_GONK) CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get()); nsScreenGonk* screen = static_cast<nsWindow*>(mCompositor->GetWidget())->GetScreen(); if (!screen->IsPrimaryScreen()) { // Only primary screen support mirroring return; } nsWindow* mirrorScreenWidget = screen->GetMirroringWidget(); if (!mirrorScreenWidget) { // No mirroring return; } nsScreenGonk* mirrorScreen = mirrorScreenWidget->GetScreen(); if (!mirrorScreen->GetTopWindows().IsEmpty()) { return; } EGLSurface surface = mirrorScreen->GetEGLSurface(); if (surface == LOCAL_EGL_NO_SURFACE) { // Create GLContext nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateForWindow(mirrorScreenWidget); mirrorScreenWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT, reinterpret_cast<uintptr_t>(gl.get())); surface = mirrorScreen->GetEGLSurface(); if (surface == LOCAL_EGL_NO_SURFACE) { // Failed to create EGLSurface return; } } GLContext* gl = compositor->gl(); GLContextEGL* egl = GLContextEGL::Cast(gl); const IntSize windowSize = mirrorScreen->GetNaturalBounds().Size(); #endif if ((windowSize.width <= 0) || (windowSize.height <= 0)) { return; } ScreenRotation rotation = compositor->GetScreenRotation(); const int actualWidth = windowSize.width; const int actualHeight = windowSize.height; const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize(); const nsIntRect originalRect = nsIntRect(0, 0, originalSize.width, originalSize.height); int pageWidth = originalSize.width; int pageHeight = originalSize.height; if (rotation == ROTATION_90 || rotation == ROTATION_270) { pageWidth = originalSize.height; pageHeight = originalSize.width; } float scale = 1.0; if ((pageWidth > actualWidth) || (pageHeight > actualHeight)) { const float scaleWidth = (float)actualWidth / (float)pageWidth; const float scaleHeight = (float)actualHeight / (float)pageHeight; scale = scaleWidth <= scaleHeight ? scaleWidth : scaleHeight; } const gfx::IntSize actualSize(actualWidth, actualHeight); ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize); const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0); ScopedContextSurfaceOverride overrideSurface(egl, surface); Matrix viewMatrix = ComputeTransformForRotation(originalRect, rotation); viewMatrix.Invert(); // unrotate viewMatrix.PostScale(scale, scale); viewMatrix.PostTranslate(offset.x, offset.y); Matrix4x4 matrix = Matrix4x4::From2D(viewMatrix); mRoot->ComputeEffectiveTransforms(matrix); nsIntRegion opaque; ApplyOcclusionCulling(mRoot, opaque); nsIntRegion invalid; Rect bounds(0.0f, 0.0f, scale * pageWidth, (float)actualHeight); Rect rect, actualBounds; mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds); // The Java side of Fennec sets a scissor rect that accounts for // chrome such as the URL bar. Override that so that the entire frame buffer // is cleared. ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight); egl->fClearColor(0.0, 0.0, 0.0, 0.0); egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT); const IntRect clipRect = IntRect(0, 0, actualWidth, actualHeight); RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect)); RootLayer()->RenderLayer(clipRect); mCompositor->EndFrame(); mCompositor->SetDispAcquireFence(mRoot); // Call after EndFrame() #ifdef MOZ_WIDGET_GONK nsRefPtr<Composer2D> composer2D; composer2D = mCompositor->GetWidget()->GetComposer2D(); if (composer2D) { composer2D->Render(mirrorScreenWidget); } #endif }
static RefPtr<TextureSource> SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor) { MOZ_ASSERT(abstractSurf); MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Basic); MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Gralloc); if (!compositor) { return nullptr; } gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8; RefPtr<TextureSource> texSource; switch (abstractSurf->mType) { #ifdef XP_WIN case gl::SharedSurfaceType::EGLSurfaceANGLE: { auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf); MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11); CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(compositor); RefPtr<ID3D11Texture2D> tex = surf->GetConsumerTexture(); if (!tex) { NS_WARNING("Failed to open shared resource."); break; } texSource = new DataTextureSourceD3D11(format, compositorD3D11, tex); break; } #endif case gl::SharedSurfaceType::GLTextureShare: { auto surf = gl::SharedSurface_GLTexture::Cast(abstractSurf); MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor); gl::GLContext* gl = compositorOGL->gl(); GLenum target = surf->ConsTextureTarget(); GLuint tex = surf->ConsTexture(gl); texSource = new GLTextureSource(compositorOGL, tex, target, surf->mSize, format, true/*externally owned*/); break; } case gl::SharedSurfaceType::EGLImageShare: { auto surf = gl::SharedSurface_EGLImage::Cast(abstractSurf); MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor); gl::GLContext* gl = compositorOGL->gl(); MOZ_ASSERT(gl->IsCurrent()); GLenum target = 0; GLuint tex = 0; surf->AcquireConsumerTexture(gl, &tex, &target); texSource = new GLTextureSource(compositorOGL, tex, target, surf->mSize, format, true/*externally owned*/); break; } #ifdef XP_MACOSX case gl::SharedSurfaceType::IOSurface: { auto surf = gl::SharedSurface_IOSurface::Cast(abstractSurf); MacIOSurface* ioSurf = surf->GetIOSurface(); MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor); texSource = new MacIOSurfaceTextureSourceOGL(compositorOGL, ioSurf); break; } #endif default: break; } MOZ_ASSERT(texSource.get(), "TextureSource creation failed."); return texSource; }