void CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { GLScreenBuffer* screen = aLayer->mGLContext->Screen(); SurfaceStream* stream = screen->Stream(); bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); bool bufferCreated = false; if (isCrossProcess) { #ifdef MOZ_WIDGET_GONK SharedSurface* surf = stream->SwapConsumer(); if (!surf) { printf_stderr("surf is null post-SwapConsumer!\n"); return; } if (surf->Type() != SharedSurfaceType::Gralloc) { printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!"); MOZ_ASSERT(false); return; } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); GrallocTextureClientOGL* grallocTextureClient = static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient()); // If IPDLActor is null means this TextureClient didn't AddTextureClient yet if (!grallocTextureClient->GetIPDLActor()) { grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags); AddTextureClient(grallocTextureClient); } if (grallocTextureClient->GetIPDLActor()) { GetForwarder()->UseTexture(this, grallocTextureClient); } #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); #endif } else { if (!mBuffer) { StreamTextureClientOGL* textureClient = new StreamTextureClientOGL(mTextureInfo.mTextureFlags); textureClient->InitWith(stream); mBuffer = textureClient; bufferCreated = true; } if (bufferCreated && !AddTextureClient(mBuffer)) { mBuffer = nullptr; } if (mBuffer) { GetForwarder()->UseTexture(this, mBuffer); } } aLayer->Painted(); }
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(); }
/** * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want, * unless mDelayedUpdates is true because of a too-large surface. */ void CanvasLayerOGL::UpdateSurface() { if (!IsDirty()) return; Painted(); if (mDestroyed || mDelayedUpdates) { return; } #if defined(GL_PROVIDER_GLX) if (mPixmap) { return; } #endif gfxASurface* updatedSurface = nullptr; gfxImageSurface* temporarySurface = nullptr; bool nothingToShow = false; if (mGLContext) { SharedSurface* surf = mGLContext->RequestFrame(); if (surf) { mLayerProgram = surf->HasAlpha() ? RGBALayerProgramType : RGBXLayerProgramType; switch (surf->Type()) { case SharedSurfaceType::Basic: { SharedSurface_Basic* readbackSurf = SharedSurface_Basic::Cast(surf); updatedSurface = readbackSurf->GetData(); break; } case SharedSurfaceType::GLTextureShare: { SharedSurface_GLTexture* textureSurf = SharedSurface_GLTexture::Cast(surf); mTexture = textureSurf->Texture(); break; } #ifdef XP_MACOSX case SharedSurfaceType::IOSurface: { SharedSurface_IOSurface *ioSurf = SharedSurface_IOSurface::Cast(surf); mTexture = ioSurf->Texture(); mTextureTarget = ioSurf->TextureTarget(); mLayerProgram = ioSurf->HasAlpha() ? RGBARectLayerProgramType : RGBXRectLayerProgramType; break; } #endif default: MOZ_CRASH("Unacceptable SharedSurface type."); } } else { nothingToShow = true; } } else if (mCanvasSurface) { #ifdef XP_MACOSX if (mDrawTarget && mDrawTarget->GetNativeSurface(gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED)) { if (!mTexture) { mTexture = MakeIOSurfaceTexture((CGContextRef)mDrawTarget->GetNativeSurface( gfx::NATIVE_SURFACE_CGCONTEXT_ACCELERATED), gl()); mTextureTarget = LOCAL_GL_TEXTURE_RECTANGLE_ARB; mLayerProgram = RGBARectLayerProgramType; } mDrawTarget->Flush(); return; } #endif updatedSurface = mCanvasSurface; } else { MOZ_CRASH("Unhandled canvas layer type."); } if (updatedSurface) { mOGLManager->MakeCurrent(); gfx::SurfaceFormat format = gl()->UploadSurfaceToTexture(updatedSurface, mBounds, mUploadTexture, true,//false, nsIntPoint(0, 0)); mLayerProgram = ShaderProgramFromSurfaceFormat(format); mTexture = mUploadTexture; if (temporarySurface) delete temporarySurface; } MOZ_ASSERT(mTexture || nothingToShow); }
void DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { if (!mDeprecatedTextureClient) { mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_STREAM_GL, aLayer->GetSurfaceMode() == SurfaceMode::SURFACE_OPAQUE ? gfxContentType::COLOR : gfxContentType::COLOR_ALPHA); MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client"); } NS_ASSERTION(aLayer->mGLContext, "CanvasClientSurfaceStream should only be used with GL canvases"); // the content type won't be used mDeprecatedTextureClient->EnsureAllocated(aSize, gfxContentType::COLOR); GLScreenBuffer* screen = aLayer->mGLContext->Screen(); SurfaceStream* stream = nullptr; if (aLayer->mStream) { stream = aLayer->mStream; stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory); stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height)); } else { stream = screen->Stream(); } bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_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); //XXX todo //mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor()); #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); #endif } else { SurfaceStreamHandle handle = stream->GetShareHandle(); mDeprecatedTextureClient->SetDescriptor(SurfaceStreamDescriptor(handle, false)); // Bug 894405 // // Ref this so the SurfaceStream doesn't disappear unexpectedly. The // Compositor will need to unref it when finished. aLayer->mGLContext->AddRef(); } aLayer->Painted(); }
void CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { aLayer->mGLContext->MakeCurrent(); GLScreenBuffer* screen = aLayer->mGLContext->Screen(); SurfaceStream* stream = nullptr; if (aLayer->mStream) { stream = aLayer->mStream; // Copy our current surface to the current producer surface in our stream, then // call SwapProducer to make a new buffer ready. stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory); stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height)); } else { stream = screen->Stream(); } bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); bool bufferCreated = false; if (isCrossProcess) { #ifdef MOZ_WIDGET_GONK SharedSurface* surf = stream->SwapConsumer(); if (!surf) { printf_stderr("surf is null post-SwapConsumer!\n"); return; } if (surf->Type() != SharedSurfaceType::Gralloc) { printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!"); MOZ_ASSERT(false); return; } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); RefPtr<GrallocTextureClientOGL> grallocTextureClient = static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient()); // If IPDLActor is null means this TextureClient didn't AddTextureClient yet if (!grallocTextureClient->GetIPDLActor()) { grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags); AddTextureClient(grallocTextureClient); } if (grallocTextureClient->GetIPDLActor()) { UseTexture(grallocTextureClient); } if (mBuffer && CompositorChild::ChildProcessHasCompositor()) { // remove old buffer from CompositableHost RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mBuffer); mBuffer->SetRemoveFromCompositableTracker(tracker); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mBuffer); } mBuffer = grallocTextureClient; #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); #endif } else { if (!mBuffer) { StreamTextureClientOGL* textureClient = new StreamTextureClientOGL(mTextureInfo.mTextureFlags); textureClient->InitWith(stream); mBuffer = textureClient; bufferCreated = true; } if (bufferCreated && !AddTextureClient(mBuffer)) { mBuffer = nullptr; } if (mBuffer) { GetForwarder()->UseTexture(this, mBuffer); } } aLayer->Painted(); }
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; }
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 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; }
void CanvasLayerD3D10::UpdateSurface() { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); } else if (mIsD2DTexture) { mSurface->Flush(); return; } if (mGLContext) { SharedSurface* surf = mGLContext->RequestFrame(); if (!surf) return; switch (surf->Type()) { case SharedSurfaceType::EGLSurfaceANGLE: { SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf); mSRView = shareSurf->GetSRV(); return; } case SharedSurfaceType::Basic: { SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf); // WebGL reads entire surface. D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to map CanvasLayer texture."); return; } gfxImageSurface* frameData = shareSurf->GetData(); // Scope for gfxContext, so it's destroyed before Unmap. { nsRefPtr<gfxImageSurface> mapSurf = new gfxImageSurface((uint8_t*)map.pData, shareSurf->Size(), map.RowPitch, gfxASurface::ImageFormatARGB32); nsRefPtr<gfxContext> ctx = new gfxContext(mapSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(frameData); ctx->Paint(); mapSurf->Flush(); } mTexture->Unmap(0); mSRView = mUploadSRView; break; } default: MOZ_CRASH("Unhandled SharedSurfaceType."); } } else if (mSurface) { RECT r; r.left = 0; r.top = 0; r.right = mBounds.width; r.bottom = mBounds.height; D3D10_MAPPED_TEXTURE2D map; HRESULT hr = mTexture->Map(0, D3D10_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } nsRefPtr<gfxImageSurface> dstSurface; dstSurface = new gfxImageSurface((unsigned char*)map.pData, gfxIntSize(mBounds.width, mBounds.height), map.RowPitch, gfxASurface::ImageFormatARGB32); nsRefPtr<gfxContext> ctx = new gfxContext(dstSurface); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(mSurface); ctx->Paint(); mTexture->Unmap(0); mSRView = mUploadSRView; } }