void CanvasLayerD3D9::UpdateSurface() { if (!IsDirty() && mTexture) return; Painted(); if (!mTexture) { CreateTexture(); if (!mTexture) { NS_WARNING("CanvasLayerD3D9::Updated called but no texture present and creation failed!"); return; } } RefPtr<SourceSurface> surface; if (mGLContext) { SharedSurface* surf = mGLContext->RequestFrame(); if (!surf) return; SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf); surface = shareSurf->GetData(); } else { surface = mDrawTarget->Snapshot(); } // WebGL reads entire surface. LockTextureRectD3D9 textureLock(mTexture); if (!textureLock.HasLock()) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } D3DLOCKED_RECT rect = textureLock.GetLockRect(); IntSize boundsSize(mBounds.width, mBounds.height); RefPtr<DrawTarget> rectDt = Factory::CreateDrawTargetForData(BackendType::CAIRO, (uint8_t*)rect.pBits, boundsSize, rect.Pitch, SurfaceFormat::B8G8R8A8); Rect drawRect(0, 0, surface->GetSize().width, surface->GetSize().height); rectDt->DrawSurface(surface, drawRect, drawRect, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); rectDt->Flush(); }
/** * 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 CanvasLayerD3D9::UpdateSurface() { if (!IsDirty() && mTexture) return; Painted(); if (!mTexture) { CreateTexture(); if (!mTexture) { NS_WARNING("CanvasLayerD3D9::Updated called but no texture present and creation failed!"); return; } } if (mGLContext) { SharedSurface* surf = mGLContext->RequestFrame(); if (!surf) return; SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf); // WebGL reads entire surface. LockTextureRectD3D9 textureLock(mTexture); if (!textureLock.HasLock()) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } D3DLOCKED_RECT rect = textureLock.GetLockRect(); DataSourceSurface* frameData = shareSurf->GetData(); // Scope for gfxContext, so it's destroyed early. { RefPtr<DrawTarget> mapDt = Factory::CreateDrawTargetForData(BACKEND_CAIRO, (uint8_t*)rect.pBits, shareSurf->Size(), rect.Pitch, FORMAT_B8G8R8A8); nsRefPtr<gfxImageSurface> thebesFrameData = new gfxImageSurface(frameData->GetData(), ThebesIntSize(frameData->GetSize()), frameData->Stride(), SurfaceFormatToImageFormat(frameData->GetFormat())); nsRefPtr<gfxContext> ctx = new gfxContext(mapDt); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(thebesFrameData); ctx->Paint(); mapDt->Flush(); } } else { RECT r; r.left = mBounds.x; r.top = mBounds.y; r.right = mBounds.XMost(); r.bottom = mBounds.YMost(); LockTextureRectD3D9 textureLock(mTexture); if (!textureLock.HasLock()) { NS_WARNING("Failed to lock CanvasLayer texture."); return; } D3DLOCKED_RECT lockedRect = textureLock.GetLockRect(); nsRefPtr<gfxImageSurface> sourceSurface; if (mSurface->GetType() == gfxSurfaceTypeWin32) { sourceSurface = mSurface->GetAsImageSurface(); } else if (mSurface->GetType() == gfxSurfaceTypeImage) { sourceSurface = static_cast<gfxImageSurface*>(mSurface.get()); if (sourceSurface->Format() != gfxImageFormatARGB32 && sourceSurface->Format() != gfxImageFormatRGB24) { return; } } else { sourceSurface = new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height), gfxImageFormatARGB32); nsRefPtr<gfxContext> ctx = new gfxContext(sourceSurface); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(mSurface); ctx->Paint(); } uint8_t *startBits = sourceSurface->Data(); uint32_t sourceStride = sourceSurface->Stride(); if (sourceSurface->Format() != gfxImageFormatARGB32) { mHasAlpha = false; } else { mHasAlpha = true; } for (int y = 0; y < mBounds.height; y++) { memcpy((uint8_t*)lockedRect.pBits + lockedRect.Pitch * y, startBits + sourceStride * y, mBounds.width * 4); } } }
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; } }
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; } }