DIBTextureHost::DIBTextureHost(TextureFlags aFlags, const SurfaceDescriptorDIB& aDescriptor) : TextureHost(aFlags) , mIsLocked(false) { // We added an extra ref for transport, so we shouldn't AddRef now. mSurface = dont_AddRef(reinterpret_cast<gfxWindowsSurface*>(aDescriptor.surface())); MOZ_ASSERT(mSurface); mSize = ToIntSize(mSurface->GetSize()); mFormat = ImageFormatToSurfaceFormat( gfxPlatform::GetPlatform()->OptimalFormatForContent(mSurface->GetContentType())); }
void ContentClientBasic::CreateBuffer(ContentType aType, const IntRect& aRect, uint32_t aFlags, RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) { MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA)); gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(aType); *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( IntSize(aRect.width, aRect.height), ImageFormatToSurfaceFormat(format)); }
void ContentClientBasic::CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags, gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface, RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) { MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA)); if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(aType); *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( IntSize(aRect.width, aRect.height), ImageFormatToSurfaceFormat(format)); return; } nsRefPtr<gfxASurface> referenceSurface = GetBuffer(); if (!referenceSurface) { gfxContext* defaultTarget = mManager->GetDefaultTarget(); if (defaultTarget) { referenceSurface = defaultTarget->CurrentSurface(); } else { nsIWidget* widget = mManager->GetRetainerWidget(); if (!widget || !(referenceSurface = widget->GetThebesSurface())) { referenceSurface = mManager->GetTarget()->CurrentSurface(); } } } nsRefPtr<gfxASurface> ret = referenceSurface->CreateSimilarSurface( aType, gfxIntSize(aRect.width, aRect.height)); *aBlackSurface = ret.forget().get(); }
void ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) { gl->MakeCurrent(); MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0)); /* gfxImageFormat::ARGB32: * RGBA+UByte: be[RGBA], le[ABGR] * RGBA+UInt: le[RGBA] * BGRA+UInt: le[BGRA] * BGRA+UIntRev: le[ARGB] * * gfxImageFormat::RGB16_565: * RGB+UShort: le[rrrrrggg,gggbbbbb] */ bool hasAlpha = dest->Format() == gfxImageFormat::ARGB32; int destPixelSize; GLenum destFormat; GLenum destType; switch (dest->Format()) { case gfxImageFormat::RGB24: // XRGB case gfxImageFormat::ARGB32: destPixelSize = 4; // Needs host (little) endian ARGB. destFormat = LOCAL_GL_BGRA; destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; break; case gfxImageFormat::RGB16_565: destPixelSize = 2; destFormat = LOCAL_GL_RGB; destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV; break; default: MOZ_CRASH("Bad format."); } MOZ_ASSERT(dest->Stride() == dest->Width() * destPixelSize); GLenum readFormat = destFormat; GLenum readType = destType; bool needsTempSurf = !GetActualReadFormats(gl, destFormat, destType, readFormat, readType); nsAutoPtr<gfxImageSurface> tempSurf; gfxImageSurface* readSurf = nullptr; int readPixelSize = 0; if (needsTempSurf) { if (gl->DebugMode()) { NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!"); } SurfaceFormat readFormatGFX; switch (readFormat) { case LOCAL_GL_RGBA: case LOCAL_GL_BGRA: { readFormatGFX = hasAlpha ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; break; } case LOCAL_GL_RGB: { MOZ_ASSERT(readPixelSize == 2); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV); readFormatGFX = SurfaceFormat::R5G6B5; break; } default: { MOZ_CRASH("Bad read format."); } } switch (readType) { case LOCAL_GL_UNSIGNED_BYTE: { MOZ_ASSERT(readFormat == LOCAL_GL_RGBA); readPixelSize = 4; break; } case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: { MOZ_ASSERT(readFormat == LOCAL_GL_BGRA); readPixelSize = 4; break; } case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: { MOZ_ASSERT(readFormat == LOCAL_GL_RGB); readPixelSize = 2; break; } default: { MOZ_CRASH("Bad read type."); } } tempSurf = new gfxImageSurface(dest->GetSize(), SurfaceFormatToImageFormat(readFormatGFX), false); readSurf = tempSurf; } else { readPixelSize = destPixelSize; readSurf = dest; } MOZ_ASSERT(readPixelSize); GLint currentPackAlignment = 0; gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, ¤tPackAlignment); if (currentPackAlignment != readPixelSize) gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readPixelSize); GLsizei width = dest->Width(); GLsizei height = dest->Height(); readSurf->Flush(); gl->fReadPixels(0, 0, width, height, readFormat, readType, readSurf->Data()); readSurf->MarkDirty(); if (currentPackAlignment != readPixelSize) gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); if (readSurf != dest) { MOZ_ASSERT(readFormat == LOCAL_GL_RGBA); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE); // So we just copied in RGBA in big endian, or le: 0xAABBGGRR. // We want 0xAARRGGBB, so swap R and B: dest->Flush(); RefPtr<DataSourceSurface> readDSurf = Factory::CreateWrappingDataSourceSurface(readSurf->Data(), readSurf->Stride(), ToIntSize(readSurf->GetSize()), ImageFormatToSurfaceFormat(readSurf->Format())); SwapRAndBComponents(readDSurf); dest->MarkDirty(); gfxContext ctx(dest); ctx.SetOperator(gfxContext::OPERATOR_SOURCE); ctx.SetSource(readSurf); ctx.Paint(); } // Check if GL is giving back 1.0 alpha for // RGBA reads to RGBA images from no-alpha buffers. #ifdef XP_MACOSX if (gl->WorkAroundDriverBugs() && gl->Vendor() == gl::GLVendor::NVIDIA && dest->Format() == gfxImageFormat::ARGB32 && width && height) { GLint alphaBits = 0; gl->fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits); if (!alphaBits) { const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0); dest->Flush(); uint32_t* itr = (uint32_t*)dest->Data(); uint32_t testPixel = *itr; if ((testPixel & alphaMask) != alphaMask) { // We need to set the alpha channel to 1.0 manually. uint32_t* itrEnd = itr + width*height; // Stride is guaranteed to be width*4. for (; itr != itrEnd; itr++) { *itr |= alphaMask; } } dest->MarkDirty(); } } #endif }