Bug 1398277: special-case retriggering of tasks not in the taskgraph; r=bstack
This will apply to cron tasks, action tasks, and decision tasks. It is a
distinct retrigger implementation because (a) we do not want to follow
dependencies, and (b) it takes a lot of scopes to create a decision task, so we
need to limit access to this action.
MozReview-Commit-ID: 21DVSiagcrO

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim: set ts=8 sts=2 et sw=2 tw=80: *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#include"TextureDIB.h"#include"gfx2DGlue.h"#include"mozilla/gfx/DataSurfaceHelpers.h" // For BufferSizeFromDimensions#include"mozilla/ipc/ProtocolUtils.h"#include"mozilla/layers/ISurfaceAllocator.h"#include"mozilla/layers/TextureForwarder.h" // For LayersIPCChannelnamespacemozilla{usingnamespacegfx;namespacelayers{/** * Can only be drawn into through Cairo. * The coresponding TextureHost depends on the compositor */classMemoryDIBTextureData:publicDIBTextureData{public:virtualboolSerialize(SurfaceDescriptor&aOutDescriptor)override;virtualTextureData*CreateSimilar(LayersIPCChannel*aAllocator,LayersBackendaLayersBackend,TextureFlagsaFlags=TextureFlags::DEFAULT,TextureAllocationFlagsaAllocFlags=ALLOC_DEFAULT)constoverride;virtualboolUpdateFromSurface(gfx::SourceSurface*aSurface)override;staticDIBTextureData*Create(gfx::IntSizeaSize,gfx::SurfaceFormataFormat);virtualvoidDeallocate(LayersIPCChannel*aAllocator)override{mSurface=nullptr;}MemoryDIBTextureData(gfx::IntSizeaSize,gfx::SurfaceFormataFormat,gfxWindowsSurface*aSurface):DIBTextureData(aSize,aFormat,aSurface){MOZ_COUNT_CTOR(MemoryDIBTextureData);}virtual~MemoryDIBTextureData(){MOZ_COUNT_DTOR(MemoryDIBTextureData);}};/** * Can only be drawn into through Cairo. * The coresponding TextureHost depends on the compositor */classShmemDIBTextureData:publicDIBTextureData{public:virtualboolSerialize(SurfaceDescriptor&aOutDescriptor)override;virtualTextureData*CreateSimilar(LayersIPCChannel*aAllocator,LayersBackendaLayersBackend,TextureFlagsaFlags=TextureFlags::DEFAULT,TextureAllocationFlagsaAllocFlags=ALLOC_DEFAULT)constoverride;virtualboolUpdateFromSurface(gfx::SourceSurface*aSurface)override;staticDIBTextureData*Create(gfx::IntSizeaSize,gfx::SurfaceFormataFormat,LayersIPCChannel*aAllocator);voidDeallocateData(){if(mSurface){::DeleteObject(mBitmap);::DeleteDC(mDC);::CloseHandle(mFileMapping);mBitmap=NULL;mDC=NULL;mFileMapping=NULL;mSurface=nullptr;}}virtualvoidDeallocate(LayersIPCChannel*aAllocator)override{DeallocateData();}ShmemDIBTextureData(gfx::IntSizeaSize,gfx::SurfaceFormataFormat,gfxWindowsSurface*aSurface,HANDLEaFileMapping,HANDLEaHostHandle,HDCaDC,HBITMAPaBitmap):DIBTextureData(aSize,aFormat,aSurface),mFileMapping(aFileMapping),mHostHandle(aHostHandle),mDC(aDC),mBitmap(aBitmap){MOZ_COUNT_CTOR(ShmemDIBTextureData);}virtual~ShmemDIBTextureData(){MOZ_COUNT_DTOR(ShmemDIBTextureData);// The host side has its own references and handles to this data, we can// safely clear ours.DeallocateData();}HANDLEmFileMapping;HANDLEmHostHandle;HDCmDC;HBITMAPmBitmap;};voidDIBTextureData::FillInfo(TextureData::Info&aInfo)const{aInfo.size=mSize;aInfo.format=mFormat;aInfo.hasIntermediateBuffer=true;aInfo.hasSynchronization=false;aInfo.supportsMoz2D=true;aInfo.canExposeMappedData=false;}already_AddRefed<gfx::DrawTarget>DIBTextureData::BorrowDrawTarget(){returngfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface,mSize);}DIBTextureData*DIBTextureData::Create(gfx::IntSizeaSize,gfx::SurfaceFormataFormat,LayersIPCChannel*aAllocator){if(!aAllocator){returnnullptr;}if(aFormat==gfx::SurfaceFormat::UNKNOWN){returnnullptr;}if(aAllocator->IsSameProcess()){returnMemoryDIBTextureData::Create(aSize,aFormat);}else{returnShmemDIBTextureData::Create(aSize,aFormat,aAllocator);}}TextureData*MemoryDIBTextureData::CreateSimilar(LayersIPCChannel*aAllocator,LayersBackendaLayersBackend,TextureFlagsaFlags,TextureAllocationFlagsaAllocFlags)const{if(!aAllocator){returnnullptr;}returnMemoryDIBTextureData::Create(mSize,mFormat);}boolMemoryDIBTextureData::Serialize(SurfaceDescriptor&aOutDescriptor){MOZ_ASSERT(mSurface);// The host will release this ref when it receives the surface descriptor.// We AddRef in case we die before the host receives the pointer.aOutDescriptor=SurfaceDescriptorDIB(reinterpret_cast<uintptr_t>(mSurface.get()));mSurface.get()->AddRef();returntrue;}DIBTextureData*MemoryDIBTextureData::Create(gfx::IntSizeaSize,gfx::SurfaceFormataFormat){RefPtr<gfxWindowsSurface>surface=newgfxWindowsSurface(aSize,SurfaceFormatToImageFormat(aFormat));if(!surface||surface->CairoStatus()){NS_WARNING("Could not create DIB surface");returnnullptr;}returnnewMemoryDIBTextureData(aSize,aFormat,surface);}boolMemoryDIBTextureData::UpdateFromSurface(gfx::SourceSurface*aSurface){RefPtr<gfxImageSurface>imgSurf=mSurface->GetAsImageSurface();RefPtr<DataSourceSurface>srcSurf=aSurface->GetDataSurface();if(!srcSurf){gfxCriticalError()<<"Failed to GetDataSurface in UpdateFromSurface (DIB).";returnfalse;}DataSourceSurface::MappedSurfacesourceMap;if(!srcSurf->Map(gfx::DataSourceSurface::READ,&sourceMap)){gfxCriticalError()<<"Failed to map source surface for UpdateFromSurface.";returnfalse;}for(inty=0;y<srcSurf->GetSize().height;y++){memcpy(imgSurf->Data()+imgSurf->Stride()*y,sourceMap.mData+sourceMap.mStride*y,srcSurf->GetSize().width*BytesPerPixel(srcSurf->GetFormat()));}srcSurf->Unmap();returntrue;}TextureData*ShmemDIBTextureData::CreateSimilar(LayersIPCChannel*aAllocator,LayersBackendaLayersBackend,TextureFlagsaFlags,TextureAllocationFlagsaAllocFlags)const{if(!aAllocator){returnnullptr;}returnShmemDIBTextureData::Create(mSize,mFormat,aAllocator);}boolShmemDIBTextureData::UpdateFromSurface(gfx::SourceSurface*aSurface){RefPtr<DataSourceSurface>srcSurf=aSurface->GetDataSurface();if(!srcSurf){gfxCriticalError()<<"Failed to GetDataSurface in UpdateFromSurface (DTD).";returnfalse;}DataSourceSurface::MappedSurfacesourceMap;if(!srcSurf->Map(gfx::DataSourceSurface::READ,&sourceMap)){gfxCriticalError()<<"Failed to map source surface for UpdateFromSurface.";returnfalse;}GdiFlush();uint32_tstride=mSize.width*BytesPerPixel(mFormat);uint8_t*data=(uint8_t*)::MapViewOfFile(mFileMapping,FILE_MAP_WRITE,0,0,stride*mSize.height);if(!data){gfxCriticalError()<<"Failed to map view of file for UpdateFromSurface.";srcSurf->Unmap();returnfalse;}for(inty=0;y<srcSurf->GetSize().height;y++){memcpy(data+stride*y,sourceMap.mData+sourceMap.mStride*y,srcSurf->GetSize().width*BytesPerPixel(srcSurf->GetFormat()));}::UnmapViewOfFile(data);srcSurf->Unmap();returntrue;}boolShmemDIBTextureData::Serialize(SurfaceDescriptor&aOutDescriptor){if(mFormat==gfx::SurfaceFormat::UNKNOWN){returnfalse;}::GdiFlush();aOutDescriptor=SurfaceDescriptorFileMapping((WindowsHandle)mHostHandle,mFormat,mSize);returntrue;}DIBTextureData*ShmemDIBTextureData::Create(gfx::IntSizeaSize,gfx::SurfaceFormataFormat,LayersIPCChannel*aAllocator){MOZ_ASSERT(aAllocator->GetParentPid()!=base::ProcessId());DWORDmapSize=aSize.width*aSize.height*BytesPerPixel(aFormat);HANDLEfileMapping=::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,mapSize,NULL);if(!fileMapping){gfxCriticalError()<<"Failed to create memory file mapping for "<<mapSize<<" bytes.";returnnullptr;}BITMAPV4HEADERheader;memset(&header,0,sizeof(BITMAPV4HEADER));header.bV4Size=sizeof(BITMAPV4HEADER);header.bV4Width=aSize.width;header.bV4Height=-LONG(aSize.height);// top-to-buttom DIBheader.bV4Planes=1;header.bV4BitCount=32;header.bV4V4Compression=BI_BITFIELDS;header.bV4RedMask=0x00FF0000;header.bV4GreenMask=0x0000FF00;header.bV4BlueMask=0x000000FF;HDCnulldc=::GetDC(NULL);HDCdc=::CreateCompatibleDC(nulldc);::ReleaseDC(nullptr,nulldc);if(!dc){::CloseHandle(fileMapping);gfxCriticalError()<<"Failed to create DC for bitmap.";returnnullptr;}void*bits;HBITMAPbitmap=::CreateDIBSection(dc,(BITMAPINFO*)&header,DIB_RGB_COLORS,&bits,fileMapping,0);if(!bitmap){gfxCriticalError()<<"Failed to create DIB section for a bitmap of size "<<aSize<<" and mapSize "<<mapSize;::CloseHandle(fileMapping);::DeleteDC(dc);returnnullptr;}::SelectObject(dc,bitmap);RefPtr<gfxWindowsSurface>surface=newgfxWindowsSurface(dc,0);if(surface->CairoStatus()){::DeleteObject(bitmap);::DeleteDC(dc);::CloseHandle(fileMapping);gfxCriticalError()<<"Could not create surface, status: "<<surface->CairoStatus();returnnullptr;}HANDLEhostHandle=NULL;if(!ipc::DuplicateHandle(fileMapping,aAllocator->GetParentPid(),&hostHandle,0,DUPLICATE_SAME_ACCESS)){gfxCriticalError()<<"Failed to duplicate handle to parent process for surface.";::DeleteObject(bitmap);::DeleteDC(dc);::CloseHandle(fileMapping);returnnullptr;}returnnewShmemDIBTextureData(aSize,aFormat,surface,fileMapping,hostHandle,dc,bitmap);}boolTextureHostDirectUpload::Lock(){MOZ_ASSERT(!mIsLocked);mIsLocked=true;returntrue;}voidTextureHostDirectUpload::Unlock(){MOZ_ASSERT(mIsLocked);mIsLocked=false;}voidTextureHostDirectUpload::SetTextureSourceProvider(TextureSourceProvider*aProvider){mProvider=aProvider;}voidTextureHostDirectUpload::DeallocateDeviceData(){if(mTextureSource){mTextureSource->DeallocateDeviceData();}}boolTextureHostDirectUpload::BindTextureSource(CompositableTextureSourceRef&aTexture){returnAcquireTextureSource(aTexture);}boolTextureHostDirectUpload::AcquireTextureSource(CompositableTextureSourceRef&aTexture){if(!mTextureSource){Updated();}aTexture=mTextureSource;return!!aTexture;}DIBTextureHost::DIBTextureHost(TextureFlagsaFlags,constSurfaceDescriptorDIB&aDescriptor):TextureHostDirectUpload(aFlags,SurfaceFormat::B8G8R8X8,IntSize()){// 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=mSurface->GetSize();mFormat=mSurface->GetSurfaceFormat();}voidDIBTextureHost::UpdatedInternal(constnsIntRegion*aRegion){if(!mProvider){// This can happen if we send textures to a compositable that isn't yet// attached to a layer.return;}if(!mTextureSource){mTextureSource=mProvider->CreateDataTextureSource(mFlags);}if(mSurface->CairoStatus()){gfxWarning()<<"Bad Cairo surface internal update "<<mSurface->CairoStatus();mTextureSource=nullptr;return;}RefPtr<gfxImageSurface>imgSurf=mSurface->GetAsImageSurface();RefPtr<DataSourceSurface>surf=Factory::CreateWrappingDataSourceSurface(imgSurf->Data(),imgSurf->Stride(),mSize,mFormat);if(!surf||!mTextureSource->Update(surf,const_cast<nsIntRegion*>(aRegion))){mTextureSource=nullptr;}ReadUnlock();}TextureHostFileMapping::TextureHostFileMapping(TextureFlagsaFlags,constSurfaceDescriptorFileMapping&aDescriptor):TextureHostDirectUpload(aFlags,aDescriptor.format(),aDescriptor.size()),mFileMapping((HANDLE)aDescriptor.handle()){}TextureHostFileMapping::~TextureHostFileMapping(){::CloseHandle(mFileMapping);}UserDataKeykFileMappingKey;staticvoidUnmapFileData(void*aData){MOZ_ASSERT(aData);::UnmapViewOfFile(aData);}voidTextureHostFileMapping::UpdatedInternal(constnsIntRegion*aRegion){if(!mProvider){// This can happen if we send textures to a compositable that isn't yet// attached to a layer.return;}if(!mTextureSource){mTextureSource=mProvider->CreateDataTextureSource(mFlags);}uint8_t*data=nullptr;int32_ttotalBytes=BufferSizeFromDimensions(mSize.width,mSize.height,BytesPerPixel(mFormat));if(totalBytes>0){data=(uint8_t*)::MapViewOfFile(mFileMapping,FILE_MAP_READ,0,0,totalBytes);}if(data){RefPtr<DataSourceSurface>surf=Factory::CreateWrappingDataSourceSurface(data,mSize.width*BytesPerPixel(mFormat),mSize,mFormat);if(surf){surf->AddUserData(&kFileMappingKey,data,UnmapFileData);if(!mTextureSource->Update(surf,const_cast<nsIntRegion*>(aRegion))){mTextureSource=nullptr;}}else{mTextureSource=nullptr;}}else{mTextureSource=nullptr;}ReadUnlock();}}}