bool GLScreenBuffer::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { // If the currently bound framebuffer is backed by a SharedSurface_GL // then it might want to override how we read pixel data from it. // This is normally only the default framebuffer, but we can also // have SharedSurfaces bound to other framebuffers when doing // readback for BasicLayers. SharedSurface_GL* surf; if (GetReadFB() == 0) { surf = SharedSurf(); } else { surf = mGL->mFBOMapping[GetReadFB()]; } if (surf) { return surf->ReadPixels(x, y, width, height, format, type, pixels); } return false; }
void GLScreenBuffer::Attach(SharedSurface* surface, const gfx::IntSize& size) { ScopedBindFramebuffer autoFB(mGL); SharedSurface_GL* surf = SharedSurface_GL::Cast(surface); if (mRead && SharedSurf()) SharedSurf()->UnlockProd(); surf->LockProd(); if (mRead && surf->AttachType() == SharedSurf()->AttachType() && size == Size()) { // Same size, same type, ready for reuse! mRead->Attach(surf); } else { // Else something changed, so resize: DrawBuffer* draw = CreateDraw(size); // Can be null. ReadBuffer* read = CreateRead(surf); MOZ_ASSERT(read); // Should never fail if SwapProd succeeded. delete mDraw; delete mRead; mDraw = draw; mRead = read; } // Check that we're all set up. MOZ_ASSERT(SharedSurf() == surf); if (!PreserveBuffer()) { // DiscardFramebuffer here could help perf on some mobile platforms. } }
void CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer) { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); if (mDrawTarget->GetType() == BACKEND_COREGRAPHICS_ACCELERATED) { // We have an accelerated CG context which has changed, unlike a bitmap surface // where we can alias the bits on initializing the mDrawTarget, we need to readback // and copy the accelerated surface each frame. We want to support this for quick // thumbnail but if we're going to be doing this every frame it likely is better // to use a non accelerated (bitmap) canvas. mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget); } } if (!mGLContext && aDestSurface) { nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface); tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer); return; } if (mGLContext) { if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) { MOZ_ASSERT(false, "Destination surface must be ImageSurface type."); return; } nsRefPtr<gfxImageSurface> readSurf; nsRefPtr<gfxImageSurface> resultSurf; SharedSurface* sharedSurf = mGLContext->RequestFrame(); if (!sharedSurf) { NS_WARNING("Null frame received."); return; } gfxIntSize readSize(sharedSurf->Size()); gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE) ? gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32; if (aDestSurface) { resultSurf = static_cast<gfxImageSurface*>(aDestSurface); } else { resultSurf = GetTempSurface(readSize, format); } MOZ_ASSERT(resultSurf); if (resultSurf->CairoStatus() != 0) { MOZ_ASSERT(false, "Bad resultSurf->CairoStatus()."); return; } MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL); SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf); if (surfGL->Type() == SharedSurfaceType::Basic) { SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL); readSurf = sharedSurf_Basic->GetData(); } else { if (resultSurf->Format() == format && resultSurf->GetSize() == readSize) { readSurf = resultSurf; } else { readSurf = GetTempSurface(readSize, format); } // Readback handles Flush/MarkDirty. mGLContext->Screen()->Readback(surfGL, readSurf); } MOZ_ASSERT(readSurf); bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult; if (needsPremult) { gfxImageSurface* sizedReadSurf = nullptr; if (readSurf->Format() == resultSurf->Format() && readSurf->GetSize() == resultSurf->GetSize()) { sizedReadSurf = readSurf; } else { readSurf->Flush(); nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(readSurf); ctx->Paint(); sizedReadSurf = resultSurf; } MOZ_ASSERT(sizedReadSurf); readSurf->Flush(); resultSurf->Flush(); gfxUtils::PremultiplyImageSurface(readSurf, resultSurf); resultSurf->MarkDirty(); } else if (resultSurf != readSurf) { // Didn't need premult, but we do need to blit to resultSurf readSurf->Flush(); nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(readSurf); ctx->Paint(); } // stick our surface into mSurface, so that the Paint() path is the same if (!aDestSurface) { mSurface = resultSurf; } } }
void CanvasLayerD3D10::UpdateSurface() { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); } else if (mIsD2DTexture) { return; } if (!mTexture) { return; } if (mGLContext) { SharedSurface_GL* 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; } DataSourceSurface* frameData = shareSurf->GetData(); // Scope for DrawTarget, so it's destroyed before Unmap. { IntSize boundsSize(mBounds.width, mBounds.height); RefPtr<DrawTarget> mapDt = Factory::CreateDrawTargetForData(BackendType::CAIRO, (uint8_t*)map.pData, boundsSize, map.RowPitch, SurfaceFormat::B8G8R8A8); Rect drawRect(0, 0, frameData->GetSize().width, frameData->GetSize().height); mapDt->DrawSurface(frameData, drawRect, drawRect, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mapDt->Flush(); } mTexture->Unmap(0); mSRView = mUploadSRView; break; } default: MOZ_CRASH("Unhandled SharedSurfaceType."); } } else if (mSurface) { 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; } RefPtr<DrawTarget> destTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, SurfaceFormat::R8G8B8A8); Rect r(Point(0, 0), ToRect(mBounds).Size()); destTarget->DrawSurface(mSurface, r, r, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); mTexture->Unmap(0); mSRView = mUploadSRView; } }
// |src| must begin and end locked, though we may // temporarily unlock it if we need to. void SharedSurface_GL::ProdCopy(SharedSurface_GL* src, SharedSurface_GL* dest, SurfaceFactory_GL* factory) { GLContext* gl = src->GL(); gl->MakeCurrent(); if (src->AttachType() == AttachmentType::Screen && dest->AttachType() == AttachmentType::Screen) { // Here, we actually need to blit through a temp surface, so let's make one. nsAutoPtr<SharedSurface_GLTexture> tempSurf( SharedSurface_GLTexture::Create(gl, gl, factory->Formats(), src->Size(), factory->Caps().alpha)); ProdCopy(src, tempSurf, factory); ProdCopy(tempSurf, dest, factory); return; } if (src->AttachType() == AttachmentType::Screen) { SharedSurface_GL* origLocked = gl->GetLockedSurface(); bool srcNeedsUnlock = false; bool origNeedsRelock = false; if (origLocked != src) { if (origLocked) { origLocked->UnlockProd(); origNeedsRelock = true; } src->LockProd(); srcNeedsUnlock = true; } if (dest->AttachType() == AttachmentType::GLTexture) { GLuint destTex = dest->ProdTexture(); GLenum destTarget = dest->ProdTextureTarget(); gl->BlitHelper()->BlitFramebufferToTexture(0, destTex, src->Size(), dest->Size(), destTarget); } else if (dest->AttachType() == AttachmentType::GLRenderbuffer) { GLuint destRB = dest->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer destWrapper(gl, destRB); gl->BlitHelper()->BlitFramebufferToFramebuffer(0, destWrapper.FB(), src->Size(), dest->Size()); } else { MOZ_CRASH("Unhandled dest->AttachType()."); } if (srcNeedsUnlock) src->UnlockProd(); if (origNeedsRelock) origLocked->LockProd(); return; } if (dest->AttachType() == AttachmentType::Screen) { SharedSurface_GL* origLocked = gl->GetLockedSurface(); bool destNeedsUnlock = false; bool origNeedsRelock = false; if (origLocked != dest) { if (origLocked) { origLocked->UnlockProd(); origNeedsRelock = true; } dest->LockProd(); destNeedsUnlock = true; } if (src->AttachType() == AttachmentType::GLTexture) { GLuint srcTex = src->ProdTexture(); GLenum srcTarget = src->ProdTextureTarget(); gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0, src->Size(), dest->Size(), srcTarget); } else if (src->AttachType() == AttachmentType::GLRenderbuffer) { GLuint srcRB = src->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB); gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), 0, src->Size(), dest->Size()); } else { MOZ_CRASH("Unhandled src->AttachType()."); } if (destNeedsUnlock) dest->UnlockProd(); if (origNeedsRelock) origLocked->LockProd(); return; } // Alright, done with cases involving Screen types. // Only {src,dest}x{texture,renderbuffer} left. if (src->AttachType() == AttachmentType::GLTexture) { GLuint srcTex = src->ProdTexture(); GLenum srcTarget = src->ProdTextureTarget(); if (dest->AttachType() == AttachmentType::GLTexture) { GLuint destTex = dest->ProdTexture(); GLenum destTarget = dest->ProdTextureTarget(); gl->BlitHelper()->BlitTextureToTexture(srcTex, destTex, src->Size(), dest->Size(), srcTarget, destTarget); return; } if (dest->AttachType() == AttachmentType::GLRenderbuffer) { GLuint destRB = dest->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer destWrapper(gl, destRB); gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, destWrapper.FB(), src->Size(), dest->Size(), srcTarget); return; } MOZ_CRASH("Unhandled dest->AttachType()."); } if (src->AttachType() == AttachmentType::GLRenderbuffer) { GLuint srcRB = src->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB); if (dest->AttachType() == AttachmentType::GLTexture) { GLuint destTex = dest->ProdTexture(); GLenum destTarget = dest->ProdTextureTarget(); gl->BlitHelper()->BlitFramebufferToTexture(srcWrapper.FB(), destTex, src->Size(), dest->Size(), destTarget); return; } if (dest->AttachType() == AttachmentType::GLRenderbuffer) { GLuint destRB = dest->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer destWrapper(gl, destRB); gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), destWrapper.FB(), src->Size(), dest->Size()); return; } MOZ_CRASH("Unhandled dest->AttachType()."); } MOZ_CRASH("Unhandled src->AttachType()."); }
void CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer) { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget); } if (!mGLContext && aDestSurface) { nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface); tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer); return; } if (mGLContext) { if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) { MOZ_ASSERT(false, "Destination surface must be ImageSurface type."); return; } nsRefPtr<gfxImageSurface> readSurf; nsRefPtr<gfxImageSurface> resultSurf; SharedSurface* sharedSurf = mGLContext->RequestFrame(); if (!sharedSurf) { NS_WARNING("Null frame received."); return; } gfxIntSize readSize(sharedSurf->Size()); gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE) ? gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32; if (aDestSurface) { resultSurf = static_cast<gfxImageSurface*>(aDestSurface); } else { resultSurf = GetTempSurface(readSize, format); } MOZ_ASSERT(resultSurf); if (resultSurf->CairoStatus() != 0) { MOZ_ASSERT(false, "Bad resultSurf->CairoStatus()."); return; } MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL); SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf); if (surfGL->Type() == SharedSurfaceType::Basic) { SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL); readSurf = sharedSurf_Basic->GetData(); } else { if (resultSurf->Format() == format && resultSurf->GetSize() == readSize) { readSurf = resultSurf; } else { readSurf = GetTempSurface(readSize, format); } // Readback handles Flush/MarkDirty. mGLContext->Screen()->Readback(surfGL, readSurf); } MOZ_ASSERT(readSurf); bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult; if (needsPremult) { gfxImageSurface* sizedReadSurf = nullptr; if (readSurf->Format() == resultSurf->Format() && readSurf->GetSize() == resultSurf->GetSize()) { sizedReadSurf = readSurf; } else { readSurf->Flush(); nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(readSurf); ctx->Paint(); sizedReadSurf = resultSurf; } MOZ_ASSERT(sizedReadSurf); readSurf->Flush(); resultSurf->Flush(); gfxUtils::PremultiplyImageSurface(readSurf, resultSurf); resultSurf->MarkDirty(); } else if (resultSurf != readSurf) { // Didn't need premult, but we do need to blit to resultSurf readSurf->Flush(); nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(readSurf); ctx->Paint(); } // stick our surface into mSurface, so that the Paint() path is the same if (!aDestSurface) { mSurface = resultSurf; } } }
void CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer) { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); mSurface = gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget); } if (!mGLContext && aDestSurface) { nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface); tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer); return; } if (mGLContext) { nsRefPtr<gfxImageSurface> readSurf; nsRefPtr<gfxASurface> resultSurf; SharedSurface* sharedSurf = mGLContext->RequestFrame(); if (!sharedSurf) { NS_WARNING("Null frame received."); return; } IntSize readSize(ToIntSize(sharedSurf->Size())); gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE) ? gfxImageFormatRGB24 : gfxImageFormatARGB32; if (aDestSurface) { resultSurf = aDestSurface; } else { resultSurf = GetTempSurface(readSize, format); } MOZ_ASSERT(resultSurf); if (resultSurf->CairoStatus() != 0) { MOZ_ASSERT(false, "Bad resultSurf->CairoStatus()."); return; } MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL); SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf); if (surfGL->Type() == SharedSurfaceType::Basic) { SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL); readSurf = sharedSurf_Basic->GetData(); } else { if (ToIntSize(resultSurf->GetSize()) != readSize || !(readSurf = resultSurf->GetAsImageSurface()) || readSurf->Format() != format) { readSurf = GetTempSurface(readSize, format); } // Readback handles Flush/MarkDirty. mGLContext->Screen()->Readback(surfGL, readSurf); } MOZ_ASSERT(readSurf); bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult; if (needsPremult) { readSurf->Flush(); gfxUtils::PremultiplyImageSurface(readSurf); readSurf->MarkDirty(); } if (readSurf != resultSurf) { readSurf->Flush(); nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(readSurf); ctx->Paint(); } // If !aDestSurface then we will end up painting using mSurface, so // stick our surface into mSurface, so that the Paint() path is the same. if (!aDestSurface) { mSurface = resultSurf; } } }
void CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget) { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); mSurface = mDrawTarget->Snapshot(); } if (!mGLContext && aDestTarget) { NS_ASSERTION(mSurface, "Must have surface to draw!"); if (mSurface) { aDestTarget->CopySurface(mSurface, IntRect(0, 0, mBounds.width, mBounds.height), IntPoint(0, 0)); mSurface = nullptr; } return; } if (mGLContext) { SharedSurface_GL* sharedSurf = nullptr; if (mStream) { sharedSurf = SharedSurface_GL::Cast(mStream->SwapConsumer()); } else { sharedSurf = mGLContext->RequestFrame(); } if (!sharedSurf) { NS_WARNING("Null frame received."); return; } IntSize readSize(sharedSurf->Size()); SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE) ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8; bool needsPremult = sharedSurf->HasAlpha() && !mIsGLAlphaPremult; // Try to read back directly into aDestTarget's output buffer if (aDestTarget) { uint8_t* destData; IntSize destSize; int32_t destStride; SurfaceFormat destFormat; if (aDestTarget->LockBits(&destData, &destSize, &destStride, &destFormat)) { if (destSize == readSize && destFormat == format) { RefPtr<DataSourceSurface> data = Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat); mGLContext->Screen()->Readback(sharedSurf, data); if (needsPremult) { PremultiplySurface(data); } aDestTarget->ReleaseBits(destData); return; } aDestTarget->ReleaseBits(destData); } } RefPtr<SourceSurface> resultSurf; if (sharedSurf->Type() == SharedSurfaceType::Basic && !needsPremult) { SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(sharedSurf); resultSurf = sharedSurf_Basic->GetData(); } else { RefPtr<DataSourceSurface> data = GetTempSurface(readSize, format); // Readback handles Flush/MarkDirty. mGLContext->Screen()->Readback(sharedSurf, data); if (needsPremult) { PremultiplySurface(data); } resultSurf = data; } MOZ_ASSERT(resultSurf); if (aDestTarget) { aDestTarget->CopySurface(resultSurf, IntRect(0, 0, readSize.width, readSize.height), IntPoint(0, 0)); } else { // If !aDestSurface then we will end up painting using mSurface, so // stick our surface into mSurface, so that the Paint() path is the same. mSurface = resultSurf; } } }
void CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget) { if (!IsDirty()) return; Painted(); if (mDrawTarget) { mDrawTarget->Flush(); mSurface = mDrawTarget->Snapshot(); } if (!mGLContext && aDestTarget) { NS_ASSERTION(mSurface, "Must have surface to draw!"); if (mSurface) { aDestTarget->CopySurface(mSurface, IntRect(0, 0, mBounds.width, mBounds.height), IntPoint(0, 0)); } return; } if (mGLContext) { RefPtr<DataSourceSurface> readSurf; RefPtr<SourceSurface> resultSurf; SharedSurface_GL* sharedSurf = nullptr; if (mStream) { sharedSurf = SharedSurface_GL::Cast(mStream->SwapConsumer()); } else { sharedSurf = mGLContext->RequestFrame(); } if (!sharedSurf) { NS_WARNING("Null frame received."); return; } IntSize readSize(sharedSurf->Size()); SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE) ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8; if (aDestTarget) { resultSurf = aDestTarget->Snapshot(); if (!resultSurf) { resultSurf = GetTempSurface(readSize, format); } } else { resultSurf = GetTempSurface(readSize, format); } MOZ_ASSERT(resultSurf); MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL); SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf); if (surfGL->Type() == SharedSurfaceType::Basic) { // sharedSurf_Basic->mData must outlive readSurf. Alas, readSurf may not // leave the scope it was declared in. SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL); readSurf = sharedSurf_Basic->GetData(); } else { if (resultSurf->GetSize() != readSize || !(readSurf = resultSurf->GetDataSurface()) || readSurf->GetFormat() != format) { readSurf = GetTempSurface(readSize, format); } // Readback handles Flush/MarkDirty. mGLContext->Screen()->Readback(surfGL, readSurf); } MOZ_ASSERT(readSurf); bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult; if (needsPremult) { PremultiplySurface(readSurf); } if (readSurf != resultSurf) { RefPtr<DataSourceSurface> resultDataSurface = resultSurf->GetDataSurface(); RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData(BackendType::CAIRO, resultDataSurface->GetData(), resultDataSurface->GetSize(), resultDataSurface->Stride(), resultDataSurface->GetFormat()); IntSize readSize = readSurf->GetSize(); dt->CopySurface(readSurf, IntRect(0, 0, readSize.width, readSize.height), IntPoint(0, 0)); } // If !aDestSurface then we will end up painting using mSurface, so // stick our surface into mSurface, so that the Paint() path is the same. if (!aDestTarget) { mSurface = resultSurf; } } }