void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorChild* remoteRenderer = GetRemoteRenderer()) { nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents()); SurfaceDescriptor inSnapshot; if (!bounds.IsEmpty() && mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(), gfxContentType::COLOR_ALPHA, &inSnapshot) && remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height); Rect srcRect(0, 0, bounds.width, bounds.height); dt->DrawSurface(surf, dstRect, srcRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); } mForwarder->DestroySharedSurface(&inSnapshot); } } mShadowTarget = nullptr; }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorChild* remoteRenderer = GetRemoteRenderer()) { nsIntRect bounds; mWidget->GetBounds(bounds); IntSize widgetSize = bounds.Size().ToIntSize(); SurfaceDescriptor inSnapshot, snapshot; if (mForwarder->AllocSurfaceDescriptor(widgetSize, gfxContentType::COLOR_ALPHA, &inSnapshot) && // The compositor will usually reuse |snapshot| and return // it through |outSnapshot|, but if it doesn't, it's // responsible for freeing |snapshot|. remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(snapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect widgetRect(Point(0, 0), Size(widgetSize.width, widgetSize.height)); dt->DrawSurface(surf, widgetRect, widgetRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); } if (IsSurfaceDescriptorValid(snapshot)) { mForwarder->DestroySharedSurface(&snapshot); } } } mShadowTarget = nullptr; }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) { // The compositor doesn't draw to a different sized surface // when there's a rotation. Instead we rotate the result // when drawing into dt LayoutDeviceIntRect outerBounds; mWidget->GetBounds(outerBounds); IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents()); if (mTargetRotation) { bounds = RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation); } SurfaceDescriptor inSnapshot; if (!bounds.IsEmpty() && mForwarder->AllocSurfaceDescriptor(bounds.Size(), gfxContentType::COLOR_ALPHA, &inSnapshot)) { // Make a copy of |inSnapshot| because the call to send it over IPC // will call forget() on the Shmem inside, and zero it out. SurfaceDescriptor outSnapshot = inSnapshot; if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height); Rect srcRect(0, 0, bounds.width, bounds.height); gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds.ToUnknownRect(), mTargetRotation); gfx::Matrix oldMatrix = dt->GetTransform(); dt->SetTransform(rotate * oldMatrix); dt->DrawSurface(surf, dstRect, srcRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); dt->SetTransform(oldMatrix); } mForwarder->DestroySurfaceDescriptor(&outSnapshot); } } } mShadowTarget = nullptr; }
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; } } // 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); if (mGLContext) { auto screen = mGLContext->Screen(); MOZ_ASSERT(screen); SharedSurface* surf = screen->Front()->Surf(); if (!surf) return; surf->WaitSync(); if (!ReadbackSharedSurface(surf, rectDt)) { NS_WARNING("Failed to readback into texture."); } } else { RefPtr<SourceSurface> surface = mDrawTarget->Snapshot(); Rect drawRect(0, 0, surface->GetSize().width, surface->GetSize().height); rectDt->DrawSurface(surface, drawRect, drawRect, DrawSurfaceOptions(), DrawOptions(1.0F, CompositionOp::OP_SOURCE)); rectDt->Flush(); } }
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_GL* 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(); RefPtr<DrawTarget> rectDt = Factory::CreateDrawTargetForData(BackendType::CAIRO, (uint8_t*)rect.pBits, surface->GetSize(), 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(); }
void TiledTextureImage::EndUpdate() { NS_ASSERTION(mInUpdate, "EndUpdate not in update"); if (!mUpdateDrawTarget) { // update was to a single TextureImage mImages[mCurrentImage]->EndUpdate(); mInUpdate = false; mTextureState = Valid; mTextureFormat = mImages[mCurrentImage]->GetTextureFormat(); return; } RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot(); RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface(); // upload tiles from temp surface for (unsigned i = 0; i < mImages.Length(); i++) { int xPos = (i % mColumns) * mTileSize; int yPos = (i / mColumns) * mTileSize; IntRect imageRect = IntRect(IntPoint(xPos,yPos), mImages[i]->GetSize()); nsIntRegion subregion; subregion.And(mUpdateRegion, imageRect); if (subregion.IsEmpty()) continue; subregion.MoveBy(-xPos, -yPos); // Tile-local space // copy tile from temp target gfx::DrawTarget* drawTarget = mImages[i]->BeginUpdate(subregion); MOZ_ASSERT(drawTarget->GetBackendType() == BackendType::CAIRO, "updateSnapshot should not have been converted to data"); gfxUtils::ClipToRegion(drawTarget, subregion); Size size(updateData->GetSize().width, updateData->GetSize().height); drawTarget->DrawSurface(updateData, Rect(Point(-xPos, -yPos), size), Rect(Point(0, 0), size), DrawSurfaceOptions(), DrawOptions(1.0, CompositionOp::OP_SOURCE, AntialiasMode::NONE)); drawTarget->PopClip(); mImages[i]->EndUpdate(); } mUpdateDrawTarget = nullptr; mInUpdate = false; mTextureFormat = mImages[0]->GetTextureFormat(); mTextureState = Valid; }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorChild* remoteRenderer = GetRemoteRenderer()) { // The compositor doesn't draw to a different sized surface // when there's a rotation. Instead we rotate the result // when drawing into dt nsIntRect outerBounds; mWidget->GetBounds(outerBounds); nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents()); if (mTargetRotation) { bounds = RotateRect(bounds, outerBounds, mTargetRotation); } SurfaceDescriptor inSnapshot; if (!bounds.IsEmpty() && mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(), gfxContentType::COLOR_ALPHA, &inSnapshot) && remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) { RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot); DrawTarget* dt = mShadowTarget->GetDrawTarget(); Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height); Rect srcRect(0, 0, bounds.width, bounds.height); gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation); gfx::Matrix oldMatrix = dt->GetTransform(); dt->SetTransform(oldMatrix * rotate); dt->DrawSurface(surf, dstRect, srcRect, DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_OVER)); dt->SetTransform(oldMatrix); } mForwarder->DestroySharedSurface(&inSnapshot); } } mShadowTarget = nullptr; }
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; } }