// Same as above, for YCbCr surfaces void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { // client allocation ASSERT_TRUE(client->AsTextureClientYCbCr() != nullptr); TextureClientYCbCr* texture = client->AsTextureClientYCbCr(); texture->AllocateForYCbCr(ToIntSize(ycbcrData.mYSize), ToIntSize(ycbcrData.mCbCrSize), ycbcrData.mStereoMode); ASSERT_TRUE(client->IsAllocated()); // client painting texture->UpdateYCbCr(ycbcrData); ASSERT_TRUE(client->Lock(OPEN_READ_ONLY)); client->Unlock(); // client serialization SurfaceDescriptor descriptor; ASSERT_TRUE(client->ToSurfaceDescriptor(descriptor)); ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t); // host deserialization RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr, client->GetFlags()); RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get()); ASSERT_TRUE(host.get() != nullptr); ASSERT_EQ(host->GetFlags(), client->GetFlags()); // This will work iff the compositor is not BasicCompositor ASSERT_EQ(host->GetFormat(), mozilla::gfx::FORMAT_YUV); // host read ASSERT_TRUE(host->Lock()); ASSERT_TRUE(host->GetFormat() == mozilla::gfx::FORMAT_YUV); YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer()); ASSERT_TRUE(yuvDeserializer.IsValid()); PlanarYCbCrData data; data.mYChannel = yuvDeserializer.GetYData(); data.mCbChannel = yuvDeserializer.GetCbData(); data.mCrChannel = yuvDeserializer.GetCrData(); data.mYStride = yuvDeserializer.GetYStride(); data.mCbCrStride = yuvDeserializer.GetCbCrStride(); data.mStereoMode = yuvDeserializer.GetStereoMode(); data.mYSize = yuvDeserializer.GetYSize(); data.mCbCrSize = yuvDeserializer.GetCbCrSize(); data.mYSkip = 0; data.mCbSkip = 0; data.mCrSkip = 0; data.mPicSize = data.mYSize; data.mPicX = 0; data.mPicY = 0; AssertYCbCrSurfacesEqual(&ycbcrData, &data); host->Unlock(); }
TemporaryRef<TextureHost> CreateBackendIndependentTextureHost(uint64_t aID, const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: { const SurfaceDescriptorShmem& descriptor = aDesc.get_SurfaceDescriptorShmem(); result = new ShmemTextureHost(aID, descriptor.data(), descriptor.format(), aDeallocator, aFlags); break; } case SurfaceDescriptor::TSurfaceDescriptorMemory: { const SurfaceDescriptorMemory& descriptor = aDesc.get_SurfaceDescriptorMemory(); result = new MemoryTextureHost(aID, reinterpret_cast<uint8_t*>(descriptor.data()), descriptor.format(), aFlags); break; } default: { NS_WARNING("No backend independent TextureHost for this descriptor type"); } } return result; }
// Convert pixels in graphic buffer to NV12 format. aSource is the layer image // containing source graphic buffer, and aDestination is the destination of // conversion. Currently only 2 source format are supported: // - NV21/HAL_PIXEL_FORMAT_YCrCb_420_SP (from camera preview window). // - YV12/HAL_PIXEL_FORMAT_YV12 (from video decoder). static void ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination) { // Get graphic buffer. SurfaceDescriptor handle = aSource->GetSurfaceDescriptor(); SurfaceDescriptorGralloc gralloc = handle.get_SurfaceDescriptorGralloc(); sp<GraphicBuffer> graphicBuffer = GrallocBufferActor::GetFrom(gralloc); int pixelFormat = graphicBuffer->getPixelFormat(); // Only support NV21 (from camera) or YV12 (from HW decoder output) for now. NS_ENSURE_TRUE_VOID(pixelFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP || pixelFormat == HAL_PIXEL_FORMAT_YV12); void* imgPtr = nullptr; graphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_MASK, &imgPtr); // Build PlanarYCbCrData for NV21 or YV12 buffer. PlanarYCbCrData yuv; switch (pixelFormat) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: // From camera. yuv.mYChannel = static_cast<uint8_t*>(imgPtr); yuv.mYSkip = 0; yuv.mYSize.width = graphicBuffer->getWidth(); yuv.mYSize.height = graphicBuffer->getHeight(); yuv.mYStride = graphicBuffer->getStride(); // 4:2:0. yuv.mCbCrSize.width = yuv.mYSize.width / 2; yuv.mCbCrSize.height = yuv.mYSize.height / 2; // Interleaved VU plane. yuv.mCrChannel = yuv.mYChannel + (yuv.mYStride * yuv.mYSize.height); yuv.mCrSkip = 1; yuv.mCbChannel = yuv.mCrChannel + 1; yuv.mCbSkip = 1; yuv.mCbCrStride = yuv.mYStride; ConvertPlanarYCbCrToNV12(&yuv, aDestination); break; case HAL_PIXEL_FORMAT_YV12: // From video decoder. // Android YV12 format is defined in system/core/include/system/graphics.h yuv.mYChannel = static_cast<uint8_t*>(imgPtr); yuv.mYSkip = 0; yuv.mYSize.width = graphicBuffer->getWidth(); yuv.mYSize.height = graphicBuffer->getHeight(); yuv.mYStride = graphicBuffer->getStride(); // 4:2:0. yuv.mCbCrSize.width = yuv.mYSize.width / 2; yuv.mCbCrSize.height = yuv.mYSize.height / 2; yuv.mCrChannel = yuv.mYChannel + (yuv.mYStride * yuv.mYSize.height); // Aligned to 16 bytes boundary. yuv.mCbCrStride = (yuv.mYStride / 2 + 15) & ~0x0F; yuv.mCrSkip = 0; yuv.mCbChannel = yuv.mCrChannel + (yuv.mCbCrStride * yuv.mCbCrSize.height); yuv.mCbSkip = 0; ConvertPlanarYCbCrToNV12(&yuv, aDestination); break; default: NS_ERROR("Unsupported input gralloc image type. Should never be here."); } graphicBuffer->unlock(); }
void SharedDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage, nsIntRegion* aRegion) { NS_ASSERTION(aImage.type() == SurfaceDescriptor::TSharedTextureDescriptor, "Invalid descriptor"); SharedTextureDescriptor texture = aImage.get_SharedTextureDescriptor(); SharedTextureHandle newHandle = texture.handle(); nsIntSize size = texture.size(); mSize = gfx::IntSize(size.width, size.height); if (texture.inverted()) { mFlags |= TEXTURE_NEEDS_Y_FLIP; } if (mSharedHandle && mSharedHandle != newHandle) { mGL->ReleaseSharedHandle(mShareType, mSharedHandle); } mShareType = texture.shareType(); mSharedHandle = newHandle; GLContext::SharedHandleDetails handleDetails; if (mSharedHandle && mGL->GetSharedHandleDetails(mShareType, mSharedHandle, handleDetails)) { mTextureTarget = handleDetails.mTarget; mFormat = handleDetails.mTextureFormat; } }
already_AddRefed<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: { result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); break; } case SurfaceDescriptor::TSurfaceDescriptorD3D10: { result = new DXGITextureHostD3D11(aFlags, aDesc.get_SurfaceDescriptorD3D10()); break; } case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr: { result = new DXGIYCbCrTextureHostD3D11(aFlags, aDesc.get_SurfaceDescriptorDXGIYCbCr()); break; } default: { NS_WARNING("Unsupported SurfaceDescriptor type"); } } return result.forget(); }
TemporaryRef<TextureHost> CreateTextureHostOGL(uint64_t aID, const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: { result = CreateBackendIndependentTextureHost(aID, aDesc, aDeallocator, aFlags); break; } case SurfaceDescriptor::TSharedTextureDescriptor: { const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor(); result = new SharedTextureHostOGL(aID, aFlags, desc.shareType(), desc.handle(), gfx::ToIntSize(desc.size()), desc.inverted()); break; } default: return nullptr; } return result.forget(); }
void DeprecatedTextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion* aRegion, nsIntPoint* aOffset) { MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage); YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>()); gfxIntSize gfxCbCrSize = yuvDeserializer.GetCbCrSize(); gfxIntSize size = yuvDeserializer.GetYSize(); D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = yuvDeserializer.GetYData(); initData.SysMemPitch = yuvDeserializer.GetYStride(); CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8_UNORM, size.width, size.height, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE); mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[0])); initData.pSysMem = yuvDeserializer.GetCbData(); initData.SysMemPitch = yuvDeserializer.GetCbCrStride(); desc.Width = yuvDeserializer.GetCbCrSize().width; desc.Height = yuvDeserializer.GetCbCrSize().height; mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[1])); initData.pSysMem = yuvDeserializer.GetCrData(); mDevice->CreateTexture2D(&desc, &initData, byRef(mTextures[2])); mSize = IntSize(size.width, size.height); }
// Same as above, for YCbCr surfaces void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { client->Lock(OpenMode::OPEN_READ_WRITE); UpdateYCbCrTextureClient(client, ycbcrData); client->Unlock(); // client serialization SurfaceDescriptor descriptor; ASSERT_TRUE(client->ToSurfaceDescriptor(descriptor)); ASSERT_EQ(descriptor.type(), SurfaceDescriptor::TSurfaceDescriptorBuffer); auto bufferDesc = descriptor.get_SurfaceDescriptorBuffer(); ASSERT_EQ(bufferDesc.desc().type(), BufferDescriptor::TYCbCrDescriptor); auto ycbcrDesc = bufferDesc.desc().get_YCbCrDescriptor(); ASSERT_EQ(ycbcrDesc.ySize(), ycbcrData.mYSize); ASSERT_EQ(ycbcrDesc.cbCrSize(), ycbcrData.mCbCrSize); ASSERT_EQ(ycbcrDesc.stereoMode(), ycbcrData.mStereoMode); // host deserialization RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr, client->GetFlags()); RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get()); ASSERT_TRUE(host.get() != nullptr); ASSERT_EQ(host->GetFlags(), client->GetFlags()); // host read if (host->Lock()) { // This will work iff the compositor is not BasicCompositor ASSERT_EQ(host->GetFormat(), mozilla::gfx::SurfaceFormat::YUV); host->Unlock(); } }
/*static*/ already_AddRefed<gfxASurface> ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aSurface) { SAMPLE_LABEL("ShadowLayerForwarder", "PlatformOpenDescriptor"); if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aSurface.type()) { return nullptr; } sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aSurface.get_SurfaceDescriptorGralloc()); uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN; if (OPEN_READ_WRITE == aMode) { usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; } void *vaddr; DebugOnly<status_t> status = buffer->lock(usage, &vaddr); // If we fail to lock, we'll just end up aborting anyway. MOZ_ASSERT(status == OK); gfxIntSize size = gfxIntSize(buffer->getWidth(), buffer->getHeight()); gfxImageFormat format = ImageFormatForPixelFormat(buffer->getPixelFormat()); long pixelStride = buffer->getStride(); long byteStride = pixelStride * gfxASurface::BytePerPixelFromFormat(format); nsRefPtr<gfxASurface> surf = new gfxImageSurface((unsigned char*)vaddr, size, byteStride, format); return surf->CairoStatus() ? nullptr : surf.forget(); }
TemporaryRef<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: { result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); break; } case SurfaceDescriptor::TSurfaceDescriptorD3D10: { result = new DXGITextureHostD3D11(aFlags, aDesc.get_SurfaceDescriptorD3D10()); break; } case SurfaceDescriptor::TSurfaceStreamDescriptor: { MOZ_CRASH("Should never hit this."); } default: { NS_WARNING("Unsupported SurfaceDescriptor type"); } } return result; }
void GrallocDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage, nsIntRegion*) { MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc); if (mBuffer) { // only done for hacky fix in gecko 23 for bug 862324. RegisterDeprecatedTextureHostAtGrallocBufferActor(nullptr, *mBuffer); } const SurfaceDescriptorGralloc& desc = aImage.get_SurfaceDescriptorGralloc(); mGraphicBuffer = GrallocBufferActor::GetFrom(desc); mIsRBSwapped = desc.isRBSwapped(); mFormat = SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat(), mIsRBSwapped); mTextureTarget = TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat()); DeleteTextures(); // only done for hacky fix in gecko 23 for bug 862324. // Doing this in SetBuffer is not enough, as DeprecatedImageHostBuffered::SwapTextures can // change the value of *mBuffer without calling SetBuffer again. RegisterDeprecatedTextureHostAtGrallocBufferActor(this, aImage); }
/*static*/ already_AddRefed<gfxASurface> ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor& aSurface) { if (SurfaceDescriptor::TSurfaceDescriptorX11 != aSurface.type()) { return nsnull; } return aSurface.get_SurfaceDescriptorX11().OpenForeign(); }
/*static*/ already_AddRefed<gfxASurface> ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode, const SurfaceDescriptor& aSurface) { if (SurfaceDescriptor::TShmem != aSurface.type()) { return nullptr; } return gfxSharedQuartzSurface::Open(aSurface.get_Shmem()); }
android::sp<android::GraphicBuffer> GetGraphicBufferFromDesc(SurfaceDescriptor aDesc) { MaybeMagicGrallocBufferHandle handle; if (aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc) { handle = aDesc.get_SurfaceDescriptorGralloc().buffer(); } return GetGraphicBufferFrom(handle); }
void CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { if (!mTextureClient) { mTextureClient = CreateTextureClient(TEXTURE_STREAM_GL); MOZ_ASSERT(mTextureClient, "Failed to create texture client"); } NS_ASSERTION(aLayer->mGLContext, "CanvasClientSurfaceStream should only be used with GL canvases"); // the content type won't be used mTextureClient->EnsureAllocated(aSize, gfxASurface::CONTENT_COLOR); GLScreenBuffer* screen = aLayer->mGLContext->Screen(); SurfaceStream* stream = screen->Stream(); bool isCrossProcess = !(XRE_GetProcessType() == GoannaProcessType_Default); if (isCrossProcess) { // swap staging -> consumer so we can send it to the compositor SharedSurface* surf = stream->SwapConsumer(); if (!surf) { printf_stderr("surf is null post-SwapConsumer!\n"); return; } #ifdef MOZ_WIDGET_GONK if (surf->Type() != SharedSurfaceType::Gralloc) { printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!"); return; } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); mTextureClient->SetDescriptor(grallocSurf->GetDescriptor()); #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); #endif mNeedsUpdate = true; } else { SurfaceStreamHandle handle = stream->GetShareHandle(); SurfaceDescriptor *desc = mTextureClient->GetDescriptor(); if (desc->type() != SurfaceDescriptor::TSurfaceStreamDescriptor || desc->get_SurfaceStreamDescriptor().handle() != handle) { *desc = SurfaceStreamDescriptor(handle, false); // Ref this so the SurfaceStream doesn't disappear unexpectedly. The // Compositor will need to unref it when finished. aLayer->mGLContext->AddRef(); mNeedsUpdate = true; } } aLayer->Painted(); }
TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: { result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); break; } #ifdef MOZ_WIDGET_ANDROID case SurfaceDescriptor::TSurfaceTextureDescriptor: { const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor(); result = new SurfaceTextureHost(aFlags, (AndroidSurfaceTexture*)desc.surfTex(), desc.size()); break; } #endif case SurfaceDescriptor::TEGLImageDescriptor: { const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor(); result = new EGLImageTextureHost(aFlags, (EGLImage)desc.image(), (EGLSync)desc.fence(), desc.size(), desc.hasAlpha()); break; } #ifdef XP_MACOSX case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: { const SurfaceDescriptorMacIOSurface& desc = aDesc.get_SurfaceDescriptorMacIOSurface(); result = new MacIOSurfaceTextureHostOGL(aFlags, desc); break; } #endif #ifdef MOZ_WIDGET_GONK case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: { const NewSurfaceDescriptorGralloc& desc = aDesc.get_NewSurfaceDescriptorGralloc(); result = new GrallocTextureHostOGL(aFlags, desc); break; } #endif default: return nullptr; } return result.forget(); }
void YCbCrDeprecatedTextureHostOGL::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion* aRegion, nsIntPoint* aOffset) { if (!mGL) { return; } NS_ASSERTION(aImage.type() == SurfaceDescriptor::TYCbCrImage, "SurfaceDescriptor mismatch"); YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>()); gfxIntSize gfxSize = deserializer.GetYSize(); gfxIntSize gfxCbCrSize = deserializer.GetCbCrSize(); if (!mYTexture->mTexImage || mYTexture->mTexImage->GetSize() != gfxSize) { mYTexture->mTexImage = CreateBasicTextureImage(mGL, gfxSize, gfxASurface::CONTENT_ALPHA, WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), FlagsToGLFlags(mFlags)); } if (!mCbTexture->mTexImage || mCbTexture->mTexImage->GetSize() != gfxCbCrSize) { mCbTexture->mTexImage = CreateBasicTextureImage(mGL, gfxCbCrSize, gfxASurface::CONTENT_ALPHA, WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), FlagsToGLFlags(mFlags)); } if (!mCrTexture->mTexImage || mCrTexture->mTexImage->GetSize() != gfxCbCrSize) { mCrTexture->mTexImage = CreateBasicTextureImage(mGL, gfxCbCrSize, gfxASurface::CONTENT_ALPHA, WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), FlagsToGLFlags(mFlags)); } RefPtr<gfxImageSurface> tempY = new gfxImageSurface(deserializer.GetYData(), gfxSize, deserializer.GetYStride(), gfxASurface::ImageFormatA8); RefPtr<gfxImageSurface> tempCb = new gfxImageSurface(deserializer.GetCbData(), gfxCbCrSize, deserializer.GetCbCrStride(), gfxASurface::ImageFormatA8); RefPtr<gfxImageSurface> tempCr = new gfxImageSurface(deserializer.GetCrData(), gfxCbCrSize, deserializer.GetCbCrStride(), gfxASurface::ImageFormatA8); nsIntRegion yRegion(nsIntRect(0, 0, gfxSize.width, gfxSize.height)); nsIntRegion cbCrRegion(nsIntRect(0, 0, gfxCbCrSize.width, gfxCbCrSize.height)); mYTexture->mTexImage->DirectUpdate(tempY, yRegion); mCbTexture->mTexImage->DirectUpdate(tempCb, cbCrRegion); mCrTexture->mTexImage->DirectUpdate(tempCr, cbCrRegion); }
void TextureHostDXGID3D11::UpdateImpl(const SurfaceDescriptor& aImage, nsIntRegion *aRegion) { MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorD3D10); mDevice->OpenSharedResource((HANDLE)aImage.get_SurfaceDescriptorD3D10().handle(), __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)byRef(mTextures[0])); mFormat = aImage.get_SurfaceDescriptorD3D10().hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8; D3D11_TEXTURE2D_DESC desc; mTextures[0]->GetDesc(&desc); mSize = IntSize(desc.Width, desc.Height); }
// Run the test for a texture client and a surface void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) { // client allocation ASSERT_TRUE(texture->CanExposeDrawTarget()); ASSERT_TRUE(texture->Lock(OpenMode::OPEN_READ_WRITE)); // client painting RefPtr<DrawTarget> dt = texture->BorrowDrawTarget(); RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surface); dt->CopySurface(source, IntRect(IntPoint(), source->GetSize()), IntPoint()); RefPtr<SourceSurface> snapshot = dt->Snapshot(); AssertSurfacesEqual(snapshot, source); dt = nullptr; // drop reference before calling Unlock() texture->Unlock(); // client serialization SurfaceDescriptor descriptor; ASSERT_TRUE(texture->ToSurfaceDescriptor(descriptor)); ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t); // host deserialization RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr, texture->GetFlags()); ASSERT_TRUE(host.get() != nullptr); ASSERT_EQ(host->GetFlags(), texture->GetFlags()); // host read // XXX - this can fail because lock tries to upload the texture but it needs a // Compositor to do that. We could add a DummyComposior for testing but I am // not sure it'll be worth it. Maybe always test against a BasicCompositor, // but the latter needs a widget... if (host->Lock()) { RefPtr<mozilla::gfx::DataSourceSurface> hostDataSurface = host->GetAsSurface(); RefPtr<gfxImageSurface> hostSurface = new gfxImageSurface(hostDataSurface->GetData(), hostDataSurface->GetSize(), hostDataSurface->Stride(), SurfaceFormatToImageFormat(hostDataSurface->GetFormat())); AssertSurfacesEqual(surface, hostSurface.get()); host->Unlock(); } }
// static TemporaryRef<TextureHost> TextureHost::Create(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: case SurfaceDescriptor::TSurfaceDescriptorDIB: return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TEGLImageDescriptor: case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: case SurfaceDescriptor::TSurfaceTextureDescriptor: return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TSharedSurfaceDescriptor: return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor()); case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) { return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); } else { return CreateTextureHostBasic(aDesc, aDeallocator, aFlags); } #ifdef MOZ_X11 case SurfaceDescriptor::TSurfaceDescriptorX11: { const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11(); RefPtr<TextureHost> result = new X11TextureHost(aFlags, desc); return result; } #endif #ifdef XP_WIN case SurfaceDescriptor::TSurfaceDescriptorD3D9: return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TSurfaceDescriptorD3D10: if (Compositor::GetBackend() == LayersBackend::LAYERS_D3D9) { return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags); } else { return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags); } #endif default: MOZ_CRASH("Unsupported Surface type"); } }
bool ShadowImageLayerOGL::Init(const SharedImage& aFront) { if (aFront.type() == SharedImage::TSurfaceDescriptor) { SurfaceDescriptor surface = aFront.get_SurfaceDescriptor(); if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) { SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor(); mSize = texture.size(); mSharedHandle = texture.handle(); mShareType = texture.shareType(); mInverted = texture.inverted(); } else { AutoOpenSurface autoSurf(OPEN_READ_ONLY, surface); mSize = autoSurf.Size(); mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height), autoSurf.ContentType(), LOCAL_GL_CLAMP_TO_EDGE, mForceSingleTile ? TextureImage::ForceSingleTile : TextureImage::NoFlags); } } else { YUVImage yuv = aFront.get_YUVImage(); AutoOpenSurface surfY(OPEN_READ_ONLY, yuv.Ydata()); AutoOpenSurface surfU(OPEN_READ_ONLY, yuv.Udata()); mSize = surfY.Size(); mCbCrSize = surfU.Size(); if (!mYUVTexture[0].IsAllocated()) { mYUVTexture[0].Allocate(gl()); mYUVTexture[1].Allocate(gl()); mYUVTexture[2].Allocate(gl()); } NS_ASSERTION(mYUVTexture[0].IsAllocated() && mYUVTexture[1].IsAllocated() && mYUVTexture[2].IsAllocated(), "Texture allocation failed!"); gl()->MakeCurrent(); SetClamping(gl(), mYUVTexture[0].GetTextureID()); SetClamping(gl(), mYUVTexture[1].GetTextureID()); SetClamping(gl(), mYUVTexture[2].GetTextureID()); return true; } return false; }
/*static*/ bool ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType( const SurfaceDescriptor& aDescriptor, OpenMode aMode, gfxContentType* aContent, gfxASurface** aSurface) { if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) { return false; } sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aDescriptor.get_SurfaceDescriptorGralloc()); *aContent = ContentTypeFromPixelFormat(buffer->getPixelFormat()); return true; }
/*static*/ bool ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize( const SurfaceDescriptor& aDescriptor, OpenMode aMode, gfxIntSize* aSize, gfxASurface** aSurface) { if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) { return false; } sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aDescriptor.get_SurfaceDescriptorGralloc()); *aSize = gfxIntSize(buffer->getWidth(), buffer->getHeight()); return true; }
TemporaryRef<TextureHost> CreateTextureHostBasic(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { #ifdef XP_MACOSX if (aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorMacIOSurface) { const SurfaceDescriptorMacIOSurface& desc = aDesc.get_SurfaceDescriptorMacIOSurface(); RefPtr<TextureHost> result = new MacIOSurfaceTextureHostBasic(aFlags, desc); return result; } #endif return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); }
void ShadowImageLayerOGL::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) { if (!mDestroyed) { if (aNewFront.type() == SharedImage::TSharedImageID) { // We are using ImageBridge protocol. The image data will be queried at render // time in the parent side. uint64_t newID = aNewFront.get_SharedImageID().id(); if (newID != mImageContainerID) { mImageContainerID = newID; mImageVersion = 0; } } else if (aNewFront.type() == SharedImage::TSurfaceDescriptor) { SurfaceDescriptor surface = aNewFront.get_SurfaceDescriptor(); if (surface.type() == SurfaceDescriptor::TSharedTextureDescriptor) { SharedTextureDescriptor texture = surface.get_SharedTextureDescriptor(); SharedTextureHandle newHandle = texture.handle(); mSize = texture.size(); mInverted = texture.inverted(); if (mSharedHandle && newHandle != mSharedHandle) gl()->ReleaseSharedHandle(mShareType, mSharedHandle); mSharedHandle = newHandle; mShareType = texture.shareType(); } else { AutoOpenSurface surf(OPEN_READ_ONLY, surface); gfxIntSize size = surf.Size(); if (mSize != size || !mTexImage || mTexImage->GetContentType() != surf.ContentType()) { Init(aNewFront); } // XXX this is always just ridiculously slow nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height)); mTexImage->DirectUpdate(surf.Get(), updateRegion); } } else { const YUVImage& yuv = aNewFront.get_YUVImage(); UploadSharedYUVToTexture(yuv); } } *aNewBack = aNewFront; }
TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, TextureFlags aFlags) { RefPtr<TextureHost> result; switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorShmem: case SurfaceDescriptor::TSurfaceDescriptorMemory: { result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); break; } case SurfaceDescriptor::TSharedTextureDescriptor: { const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor(); result = new SharedTextureHostOGL(aFlags, desc.shareType(), desc.handle(), desc.size(), desc.inverted()); break; } case SurfaceDescriptor::TSurfaceStreamDescriptor: { const SurfaceStreamDescriptor& desc = aDesc.get_SurfaceStreamDescriptor(); result = new StreamTextureHostOGL(aFlags, desc); break; } #ifdef XP_MACOSX case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: { const SurfaceDescriptorMacIOSurface& desc = aDesc.get_SurfaceDescriptorMacIOSurface(); result = new MacIOSurfaceTextureHostOGL(aFlags, desc); break; } #endif #ifdef MOZ_WIDGET_GONK case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: { const NewSurfaceDescriptorGralloc& desc = aDesc.get_NewSurfaceDescriptorGralloc(); result = new GrallocTextureHostOGL(aFlags, desc); break; } #endif default: return nullptr; } return result.forget(); }
already_AddRefed<TextureHost> TextureHost::Create(const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, LayersBackend aBackend, TextureFlags aFlags) { switch (aDesc.type()) { case SurfaceDescriptor::TSurfaceDescriptorBuffer: case SurfaceDescriptor::TSurfaceDescriptorDIB: case SurfaceDescriptor::TSurfaceDescriptorFileMapping: return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TEGLImageDescriptor: case SurfaceDescriptor::TSurfaceTextureDescriptor: case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TSurfaceDescriptorGralloc: case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: if (aBackend == LayersBackend::LAYERS_OPENGL) { return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); } else { return CreateTextureHostBasic(aDesc, aDeallocator, aFlags); } #ifdef MOZ_X11 case SurfaceDescriptor::TSurfaceDescriptorX11: { const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11(); return MakeAndAddRef<X11TextureHost>(aFlags, desc); } #endif #ifdef XP_WIN case SurfaceDescriptor::TSurfaceDescriptorD3D9: return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TSurfaceDescriptorD3D10: case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr: if (aBackend == LayersBackend::LAYERS_D3D9) { return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags); } else { return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags); } #endif default: MOZ_CRASH("GFX: Unsupported Surface type host"); } }
bool IsSurfaceDescriptorOwned(const SurfaceDescriptor& aDescriptor) { switch (aDescriptor.type()) { case SurfaceDescriptor::TYCbCrImage: { const YCbCrImage& ycbcr = aDescriptor.get_YCbCrImage(); return ycbcr.owner() != 0; } case SurfaceDescriptor::TRGBImage: { const RGBImage& rgb = aDescriptor.get_RGBImage(); return rgb.owner() != 0; } default: return false; } return false; }
void DeprecatedTextureClientDIB::SetDescriptor(const SurfaceDescriptor& aDescriptor) { mDescriptor = aDescriptor; mDrawTarget = nullptr; if (aDescriptor.type() == SurfaceDescriptor::T__None) { mSurface = nullptr; return; } MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorDIB); Unlock(); mSurface = reinterpret_cast<gfxWindowsSurface*>( mDescriptor.get_SurfaceDescriptorDIB().surface()); }
void SurfaceStreamHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage, nsIntRegion* aRegion) { MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceStreamDescriptor, "Invalid descriptor"); }