already_AddRefed<gfxASurface> ContentClientIncremental::GetUpdateSurface(BufferType aType, nsIntRegion& aUpdateRegion) { nsIntRect rgnSize = aUpdateRegion.GetBounds(); if (!mBufferRect.Contains(rgnSize)) { NS_ERROR("update outside of image"); return nullptr; } SurfaceDescriptor desc; if (!mForwarder->AllocSurfaceDescriptor(gfxIntSize(rgnSize.width, rgnSize.height), mContentType, &desc)) { NS_WARNING("creating SurfaceDescriptor failed!"); return nullptr; } nsRefPtr<gfxASurface> tmpASurface = ShadowLayerForwarder::OpenDescriptor(OPEN_READ_WRITE, desc); if (aType == BUFFER_BLACK) { MOZ_ASSERT(!IsSurfaceDescriptorValid(mUpdateDescriptor)); mUpdateDescriptor = desc; } else { MOZ_ASSERT(!IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)); MOZ_ASSERT(aType == BUFFER_WHITE); mUpdateDescriptorOnWhite = desc; } return tmpASurface.forget(); }
void BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip, CanvasSurface* aNewBack) { AutoOpenSurface autoSurface(OPEN_READ_ONLY, aNewFront); // Destroy mFrontBuffer if size different gfxIntSize sz = autoSurface.Size(); bool surfaceConfigChanged = sz != gfxIntSize(mBounds.width, mBounds.height); if (IsSurfaceDescriptorValid(mFrontSurface)) { AutoOpenSurface autoFront(OPEN_READ_ONLY, mFrontSurface); surfaceConfigChanged = surfaceConfigChanged || autoSurface.ContentType() != autoFront.ContentType(); } if (surfaceConfigChanged) { DestroyFrontBuffer(); mBounds.SetRect(0, 0, sz.width, sz.height); } mNeedsYFlip = needYFlip; // If mFrontBuffer if (IsSurfaceDescriptorValid(mFrontSurface)) { *aNewBack = mFrontSurface; } else { *aNewBack = null_t(); } mFrontSurface = aNewFront; }
TemporaryRef<DrawTarget> ContentClientIncremental::GetUpdateSurface(BufferType aType, const nsIntRegion& aUpdateRegion) { nsIntRect rgnSize = aUpdateRegion.GetBounds(); if (!mBufferRect.Contains(rgnSize)) { NS_ERROR("update outside of image"); return nullptr; } SurfaceDescriptor desc; if (!mForwarder->AllocSurfaceDescriptor(rgnSize.Size().ToIntSize(), mContentType, &desc)) { NS_WARNING("creating SurfaceDescriptor failed!"); Clear(); return nullptr; } if (aType == BUFFER_BLACK) { MOZ_ASSERT(!IsSurfaceDescriptorValid(mUpdateDescriptor)); mUpdateDescriptor = desc; } else { MOZ_ASSERT(!IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)); MOZ_ASSERT(aType == BUFFER_WHITE); mUpdateDescriptorOnWhite = desc; } return GetDrawTargetForDescriptor(desc, gfx::BackendType::COREGRAPHICS); }
void ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw, const nsIntRegion& aVisibleRegion, bool aDidSelfCopy) { if (IsSurfaceDescriptorValid(mUpdateDescriptor)) { mForwarder->UpdateTextureIncremental(this, TextureFront, mUpdateDescriptor, aRegionToDraw, mBufferRect, mBufferRotation); mUpdateDescriptor = SurfaceDescriptor(); } if (IsSurfaceDescriptorValid(mUpdateDescriptorOnWhite)) { mForwarder->UpdateTextureIncremental(this, TextureOnWhiteFront, mUpdateDescriptorOnWhite, aRegionToDraw, mBufferRect, mBufferRotation); mUpdateDescriptorOnWhite = SurfaceDescriptor(); } }
void TextureClientShmemYCbCr::SetDescriptor(const SurfaceDescriptor& aDescriptor) { MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TYCbCrImage); if (IsSurfaceDescriptorValid(mDescriptor)) { GetForwarder()->DestroySharedSurface(&mDescriptor); } mDescriptor = aDescriptor; MOZ_ASSERT(IsSurfaceDescriptorValid(mDescriptor)); }
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; }
LayerRenderState GrallocTextureHostOGL::GetRenderState() { if (mBuffer && IsSurfaceDescriptorValid(*mBuffer)) { uint32_t flags = mFlags & NeedsYFlip ? LAYER_RENDER_STATE_Y_FLIPPED : 0; /* * The 32 bit format of gralloc buffer is created as RGBA8888 or RGBX888 by default. * For software rendering (non-GL rendering), the content is drawn with BGRA * or BGRX. Therefore, we need to pass the RBSwapped flag for HW composer to swap format. * * For GL rendering content, the content format is RGBA or RGBX which is the same as * the pixel format of gralloc buffer and no need for the RBSwapped flag. */ if (mIsRBSwapped) { flags |= LAYER_RENDER_STATE_FORMAT_RB_SWAP; } return LayerRenderState(mGraphicBuffer.get(), mBuffer->get_SurfaceDescriptorGralloc().size(), flags); } return LayerRenderState(); }
bool DeprecatedTextureClientShmem::EnsureAllocated(gfx::IntSize aSize, gfxContentType aContentType) { if (aSize != mSize || aContentType != mContentType || !IsSurfaceDescriptorValid(mDescriptor)) { ReleaseResources(); mContentType = aContentType; mSize = aSize; if (!mForwarder->AllocSurfaceDescriptor(gfxIntSize(mSize.width, mSize.height), mContentType, &mDescriptor)) { NS_WARNING("creating SurfaceDescriptor failed!"); } if (mContentType == GFX_CONTENT_COLOR_ALPHA) { gfxASurface* surface = GetSurface(); if (!surface) { return false; } nsRefPtr<gfxContext> context = new gfxContext(surface); context->SetColor(gfxRGBA(0, 0, 0, 0)); context->SetOperator(gfxContext::OPERATOR_SOURCE); context->Paint(); } } return true; }
void ClientLayerManager::MakeSnapshotIfRequired() { if (!mShadowTarget) { return; } if (mWidget) { if (CompositorChild* remoteRenderer = GetRemoteRenderer()) { nsIntRect bounds; mWidget->GetBounds(bounds); SurfaceDescriptor inSnapshot, snapshot; if (AllocSurfaceDescriptor(bounds.Size(), gfxASurface::CONTENT_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)) { AutoOpenSurface opener(OPEN_READ_ONLY, snapshot); gfxASurface* source = opener.Get(); mShadowTarget->DrawSurface(source, source->GetSize()); } if (IsSurfaceDescriptorValid(snapshot)) { ShadowLayerForwarder::DestroySharedSurface(&snapshot); } } } mShadowTarget = nullptr; }
already_AddRefed<gfxASurface> ContentClientRemote::CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags) { NS_ABORT_IF_FALSE(!mIsNewBuffer, "Bad! Did we create a buffer twice without painting?"); mIsNewBuffer = true; if (mTextureClient) { mOldTextures.AppendElement(mTextureClient); DestroyBuffers(); } mTextureClient = CreateTextureClient(TEXTURE_CONTENT, aFlags | HostRelease); mContentType = aType; mSize = gfx::IntSize(aRect.width, aRect.height); mTextureClient->EnsureAllocated(mSize, mContentType); // note that LockSurfaceDescriptor doesn't actually lock anything MOZ_ASSERT(IsSurfaceDescriptorValid(*mTextureClient->LockSurfaceDescriptor())); CreateFrontBufferAndNotify(aRect, aFlags | HostRelease); nsRefPtr<gfxASurface> ret = mTextureClient->LockSurface(); return ret.forget(); }
// only used for hacky fix in gecko 23 for bug 862324 static void RegisterDeprecatedTextureHostAtGrallocBufferActor(DeprecatedTextureHost* aDeprecatedTextureHost, const SurfaceDescriptor& aSurfaceDescriptor) { if (IsSurfaceDescriptorValid(aSurfaceDescriptor)) { GrallocBufferActor* actor = static_cast<GrallocBufferActor*>(aSurfaceDescriptor.get_SurfaceDescriptorGralloc().bufferParent()); actor->SetDeprecatedTextureHost(aDeprecatedTextureHost); } }
void TextureClientSharedOGL::ReleaseResources() { if (!IsSurfaceDescriptorValid(mDescriptor)) { return; } MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::TSharedTextureDescriptor); mDescriptor = SurfaceDescriptor(); // It's important our handle gets released! SharedTextureHostOGL will take // care of this for us though. }
void DestroyBackBuffer() { if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) { SharedTextureDescriptor handle = mBackBuffer.get_SharedTextureDescriptor(); if (mGLContext && handle.handle()) { mGLContext->ReleaseSharedHandle(handle.shareType(), handle.handle()); mBackBuffer = SurfaceDescriptor(); } } else if (IsSurfaceDescriptorValid(mBackBuffer)) { BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); mBackBuffer = SurfaceDescriptor(); } }
gfxASurface* TextureClientShmem::GetSurface() { if (!mSurface) { if (!IsSurfaceDescriptorValid(mDescriptor)) { return nullptr; } MOZ_ASSERT(mAccessMode == ACCESS_READ_WRITE || mAccessMode == ACCESS_READ_ONLY); OpenMode mode = mAccessMode == ACCESS_READ_WRITE ? OPEN_READ_WRITE : OPEN_READ_ONLY; mSurface = ShadowLayerForwarder::OpenDescriptor(mode, mDescriptor); } return mSurface.get(); }
void TextureImageDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor) { CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor); GLContext* newGL = glCompositor ? glCompositor->gl() : nullptr; if (mGL != newGL) { mGL = newGL; mTexture = nullptr; // if we have a buffer we reupload it with the new gl context // Post landing TODO: the new DeprecatedTextureClient/Host model will make this // go away. if (newGL && mBuffer && IsSurfaceDescriptorValid(*mBuffer)) { UpdateImpl(*mBuffer); } } }
void ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes, const nsIntRegion& aFrontValidRegion, const nsIntRect& aBufferRect, const SurfaceDescriptor& aTempFrontBuffer) { OptionalThebesBuffer buffer = null_t(); if (IsSurfaceDescriptorValid(aTempFrontBuffer)) { buffer = ThebesBuffer(aTempFrontBuffer, aBufferRect, nsIntPoint(0, 0)); } mTxn->AddEdit(OpCreateThebesBuffer(NULL, Shadow(aThebes), buffer, aFrontValidRegion)); }
void TextureClientShmem::SetDescriptor(const SurfaceDescriptor& aDescriptor) { if (IsSurfaceDescriptorValid(aDescriptor)) { ReleaseResources(); mDescriptor = aDescriptor; } else { EnsureAllocated(mSize, mContentType); } mSurface = nullptr; NS_ASSERTION(mDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc || mDescriptor.type() == SurfaceDescriptor::TShmem || mDescriptor.type() == SurfaceDescriptor::TRGBImage, "Invalid surface descriptor"); }
void BasicShadowableCanvasLayer::Initialize(const Data& aData) { BasicCanvasLayer::Initialize(aData); if (!HasShadow()) return; // XXX won't get here currently; need to figure out what to do on // canvas resizes if (IsSurfaceDescriptorValid(mBackBuffer)) { AutoOpenSurface backSurface(OPEN_READ_ONLY, mBackBuffer); if (gfxIntSize(mBounds.width, mBounds.height) != backSurface.Size()) { DestroyBackBuffer(); } } }
bool ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtr<DeprecatedTextureClient>& aClient) { aClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT); MOZ_ASSERT(aClient, "Failed to create texture client"); if (!aClient->EnsureAllocated(mSize, mContentType)) { aClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK); MOZ_ASSERT(aClient, "Failed to create texture client"); if (!aClient->EnsureAllocated(mSize, mContentType)) { NS_WARNING("Could not allocate texture client"); return false; } } MOZ_ASSERT(IsSurfaceDescriptorValid(*aClient->GetDescriptor())); return true; }
void TextureClientShmem::ReleaseResources() { if (mSurface) { mSurface = nullptr; ShadowLayerForwarder::CloseDescriptor(mDescriptor); } if (mTextureInfo.mTextureFlags & HostRelease) { mDescriptor = SurfaceDescriptor(); return; } if (IsSurfaceDescriptorValid(mDescriptor)) { mForwarder->DestroySharedSurface(&mDescriptor); mDescriptor = SurfaceDescriptor(); } }
void TextureClientShmem::EnsureAllocated(gfx::IntSize aSize, gfxASurface::gfxContentType aContentType) { if (aSize != mSize || aContentType != mContentType || !IsSurfaceDescriptorValid(mDescriptor)) { ReleaseResources(); mContentType = aContentType; mSize = aSize; if (!mForwarder->AllocSurfaceDescriptor(gfxIntSize(mSize.width, mSize.height), mContentType, &mDescriptor)) { NS_WARNING("creating SurfaceDescriptor failed!"); } } }
void DeprecatedTextureClientShmem::ReleaseResources() { if (mSurface) { mSurface = nullptr; mSurfaceAsImage = nullptr; ShadowLayerForwarder::CloseDescriptor(mDescriptor); } if (!(mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_CLIENT)) { mDescriptor = SurfaceDescriptor(); return; } if (IsSurfaceDescriptorValid(mDescriptor)) { mForwarder->DestroySharedSurface(&mDescriptor); mDescriptor = SurfaceDescriptor(); } }
void ContentClientRemote::BuildTextureClient(ContentType aType, const nsIntRect& aRect, uint32_t aFlags) { NS_ABORT_IF_FALSE(!mIsNewBuffer, "Bad! Did we create a buffer twice without painting?"); mIsNewBuffer = true; if (mTextureClient) { mOldTextures.AppendElement(mTextureClient); DestroyBuffers(); } mTextureInfo.mTextureFlags = aFlags | HostRelease; mTextureClient = CreateTextureClient(TEXTURE_CONTENT); mContentType = aType; mSize = gfx::IntSize(aRect.width, aRect.height); mTextureClient->EnsureAllocated(mSize, mContentType); MOZ_ASSERT(IsSurfaceDescriptorValid(*mTextureClient->GetDescriptor())); CreateFrontBufferAndNotify(aRect); }
void BasicShadowCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer) { NS_ASSERTION(BasicManager()->InDrawing(), "Can only draw in drawing phase"); if (!IsSurfaceDescriptorValid(mFrontSurface)) { return; } AutoOpenSurface autoSurface(OPEN_READ_ONLY, mFrontSurface); nsRefPtr<gfxPattern> pat = new gfxPattern(autoSurface.Get()); pat->SetFilter(mFilter); pat->SetExtend(gfxPattern::EXTEND_PAD); gfxRect r(0, 0, mBounds.width, mBounds.height); gfxMatrix m; if (mNeedsYFlip) { m = aContext->CurrentMatrix(); aContext->Translate(gfxPoint(0.0, mBounds.height)); aContext->Scale(1.0, -1.0); } AutoSetOperator setOperator(aContext, GetOperator()); aContext->NewPath(); // No need to snap here; our transform has already taken care of it aContext->Rectangle(r); aContext->SetPattern(pat); FillWithMask(aContext, GetEffectiveOpacity(), aMaskLayer); if (mNeedsYFlip) { aContext->SetMatrix(m); } }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpCreatedTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedTexture& op = aEdit.get_OpCreatedTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); compositable->EnsureDeprecatedTextureHost(op.textureId(), op.descriptor(), compositableParent->GetCompositableManager(), op.textureInfo()); break; } case CompositableOperation::TOpCreatedIncrementalTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); compositable->EnsureDeprecatedTextureHostIncremental(compositableParent->GetCompositableManager(), op.textureInfo(), op.bufferRect()); break; } case CompositableOperation::TOpDestroyThebesBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Created double buffer")); const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositableHost = compositableParent->GetCompositableHost(); if (compositableHost->GetType() != BUFFER_CONTENT && compositableHost->GetType() != BUFFER_CONTENT_DIRECT) { return false; } DeprecatedContentHostBase* content = static_cast<DeprecatedContentHostBase*>(compositableHost); content->DestroyTextures(); break; } case CompositableOperation::TOpPaintTexture: { MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X")); const OpPaintTexture& op = aEdit.get_OpPaintTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); Layer* layer = compositable ? compositable->GetLayer() : nullptr; LayerComposite* shadowLayer = layer ? layer->AsLayerComposite() : nullptr; if (shadowLayer) { Compositor* compositor = static_cast<LayerManagerComposite*>(layer->Manager())->GetCompositor(); compositable->SetCompositor(compositor); compositable->SetLayer(layer); } else { // if we reach this branch, it most likely means that async textures // are coming in before we had time to attach the compositable to a // layer. Don't panic, it is okay in this case. it should not be // happening continuously, though. } if (layer) { RenderTraceInvalidateStart(layer, "FF00FF", layer->GetVisibleRegion().GetBounds()); } if (compositable) { const SurfaceDescriptor& descriptor = op.image(); compositable->EnsureDeprecatedTextureHost(op.textureId(), descriptor, compositableParent->GetCompositableManager(), TextureInfo()); MOZ_ASSERT(compositable->GetDeprecatedTextureHost()); SurfaceDescriptor newBack; bool shouldRecomposite = compositable->Update(descriptor, &newBack); if (IsSurfaceDescriptorValid(newBack)) { replyv.push_back(OpTextureSwap(compositableParent, nullptr, op.textureId(), newBack)); } if (IsAsync() && shouldRecomposite) { ScheduleComposition(op); } } if (layer) { RenderTraceInvalidateEnd(layer, "FF00FF"); } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); Layer* layer = compositable->GetLayer(); if (!layer || layer->GetType() != Layer::TYPE_THEBES) { return false; } ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; if (!compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion)) { return false; } replyv.push_back( OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpPaintTextureIncremental: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); SurfaceDescriptor desc = op.image(); compositable->UpdateIncremental(op.textureId(), desc, op.updatedRegion(), op.bufferRect(), op.bufferRotation()); break; } case CompositableOperation::TOpUpdatePictureRect: { const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); CompositableHost* compositable = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost(); MOZ_ASSERT(compositable); compositable->SetPictureRect(op.picture()); break; } case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); NS_ASSERTION(tileComposer, "compositable is not a tile composer"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); tileComposer->UseTiledLayerBuffer(this, tileDesc); break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseTexture: { const OpUseTexture& op = aEdit.get_OpUseTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->UseTextureHost(tex); if (IsAsync()) { ScheduleComposition(op); // Async layer updates don't trigger invalidation, manually tell the layer // that its content have changed. if (compositable->GetLayer()) { compositable->GetLayer()->SetInvalidRectToVisibleRegion(); } } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseComponentAlphaTextures: { const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); MOZ_ASSERT(texOnBlack && texOnWhite); compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); if (IsAsync()) { ScheduleComposition(op); } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUpdateTexture: { const OpUpdateTexture& op = aEdit.get_OpUpdateTexture(); RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(texture); texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion ? &op.region().get_nsIntRegion() : nullptr); // no region means invalidate the entire surface break; } default: { MOZ_ASSERT(false, "bad type"); } } return true; }
bool DeprecatedImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) { AutoLockImage autoLock(aContainer); Image *image = autoLock.GetImage(); if (!image) { return false; } if (mLastPaintedImageSerial == image->GetSerial()) { return true; } if (image->GetFormat() == PLANAR_YCBCR && EnsureDeprecatedTextureClient(TEXTURE_YCBCR)) { PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image); if (ycbcr->AsDeprecatedSharedPlanarYCbCrImage()) { AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient); SurfaceDescriptor sd; if (!ycbcr->AsDeprecatedSharedPlanarYCbCrImage()->ToSurfaceDescriptor(sd)) { return false; } if (IsSurfaceDescriptorValid(*lock.GetSurfaceDescriptor())) { GetForwarder()->DestroySharedSurface(lock.GetSurfaceDescriptor()); } *lock.GetSurfaceDescriptor() = sd; } else { AutoLockYCbCrClient clientLock(mDeprecatedTextureClient); if (!clientLock.Update(ycbcr)) { NS_WARNING("failed to update DeprecatedTextureClient (YCbCr)"); return false; } } } else if (image->GetFormat() == SHARED_TEXTURE && EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL)) { SharedTextureImage* sharedImage = static_cast<SharedTextureImage*>(image); const SharedTextureImage::Data *data = sharedImage->GetData(); SharedTextureDescriptor texture(data->mShareType, data->mHandle, data->mSize, data->mInverted); mDeprecatedTextureClient->SetDescriptor(SurfaceDescriptor(texture)); } else if (image->GetFormat() == SHARED_RGB && EnsureDeprecatedTextureClient(TEXTURE_SHMEM)) { nsIntRect rect(0, 0, image->GetSize().width, image->GetSize().height); UpdatePictureRect(rect); AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient); SurfaceDescriptor desc; if (!static_cast<DeprecatedSharedRGBImage*>(image)->ToSurfaceDescriptor(desc)) { return false; } mDeprecatedTextureClient->SetDescriptor(desc); #ifdef MOZ_WIDGET_GONK } else if (image->GetFormat() == GONK_IO_SURFACE && EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL)) { nsIntRect rect(0, 0, image->GetSize().width, image->GetSize().height); UpdatePictureRect(rect); AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient); SurfaceDescriptor desc = static_cast<GonkIOSurfaceImage*>(image)->GetSurfaceDescriptor(); if (!IsSurfaceDescriptorValid(desc)) { return false; } mDeprecatedTextureClient->SetDescriptor(desc); } else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) { EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL); nsIntRect rect(0, 0, image->GetSize().width, image->GetSize().height); UpdatePictureRect(rect); AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient); SurfaceDescriptor desc = static_cast<GrallocPlanarYCbCrImage*>(image)->GetSurfaceDescriptor(); if (!IsSurfaceDescriptorValid(desc)) { return false; } mDeprecatedTextureClient->SetDescriptor(desc); #endif } else { nsRefPtr<gfxASurface> surface = image->GetAsSurface(); MOZ_ASSERT(surface); EnsureDeprecatedTextureClient(TEXTURE_SHMEM); MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client"); AutoLockShmemClient clientLock(mDeprecatedTextureClient); if (!clientLock.Update(image, aContentFlags, surface)) { NS_WARNING("failed to update DeprecatedTextureClient"); return false; } } Updated(); if (image->GetFormat() == PLANAR_YCBCR) { PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image); UpdatePictureRect(ycbcr->GetData()->GetPictureRect()); } mLastPaintedImageSerial = image->GetSerial(); aContainer->NotifyPaintedImage(image); return true; }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpCreatedSingleBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Created single buffer")); const OpCreatedSingleBuffer& op = aEdit.get_OpCreatedSingleBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); TextureParent* textureParent = static_cast<TextureParent*>(op.bufferParent()); textureParent->EnsureTextureHost(op.descriptor().type()); textureParent->GetTextureHost()->SetBuffer(new SurfaceDescriptor(op.descriptor()), compositableParent->GetCompositableManager()); ContentHostBase* content = static_cast<ContentHostBase*>(compositableParent->GetCompositableHost()); content->SetTextureHosts(textureParent->GetTextureHost()); break; } case CompositableOperation::TOpCreatedDoubleBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Created double buffer")); const OpCreatedDoubleBuffer& op = aEdit.get_OpCreatedDoubleBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); TextureParent* frontParent = static_cast<TextureParent*>(op.frontParent()); TextureParent* backParent = static_cast<TextureParent*>(op.backParent()); frontParent->EnsureTextureHost(op.frontDescriptor().type()); backParent->EnsureTextureHost(op.backDescriptor().type()); frontParent->GetTextureHost()->SetBuffer(new SurfaceDescriptor(op.frontDescriptor()), compositableParent->GetCompositableManager()); backParent->GetTextureHost()->SetBuffer(new SurfaceDescriptor(op.backDescriptor()), compositableParent->GetCompositableManager()); ContentHostBase* content = static_cast<ContentHostBase*>(compositableParent->GetCompositableHost()); content->SetTextureHosts(frontParent->GetTextureHost(), backParent->GetTextureHost()); break; } case CompositableOperation::TOpDestroyThebesBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Created double buffer")); const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); ContentHostBase* content = static_cast<ContentHostBase*>(compositableParent->GetCompositableHost()); content->DestroyTextures(); break; } case CompositableOperation::TOpPaintTexture: { MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X")); const OpPaintTexture& op = aEdit.get_OpPaintTexture(); TextureParent* textureParent = static_cast<TextureParent*>(op.textureParent()); CompositableHost* compositable = textureParent->GetCompositableHost(); Layer* layer = GetLayerFromOpPaint(op); ShadowLayer* shadowLayer = layer ? layer->AsShadowLayer() : nullptr; if (shadowLayer) { Compositor* compositor = static_cast<LayerManagerComposite*>(layer->Manager())->GetCompositor(); compositable->SetCompositor(compositor); compositable->SetLayer(layer); } else { // if we reach this branch, it most likely means that async textures // are coming in before we had time to attach the conmpositable to a // layer. Don't panic, it is okay in this case. it should not be // happening continuously, though. } if (layer) { RenderTraceInvalidateStart(layer, "FF00FF", layer->GetVisibleRegion().GetBounds()); } const SurfaceDescriptor& descriptor = op.image(); textureParent->EnsureTextureHost(descriptor.type()); MOZ_ASSERT(textureParent->GetTextureHost()); SurfaceDescriptor newBack; bool shouldRecomposite = compositable->Update(op.image(), &newBack); if (IsSurfaceDescriptorValid(newBack)) { replyv.push_back(OpTextureSwap(op.textureParent(), nullptr, newBack)); } if (shouldRecomposite && textureParent->GetCompositorID()) { CompositorParent* cp = CompositorParent::GetCompositor(textureParent->GetCompositorID()); if (cp) { cp->ScheduleComposition(); } } if (layer) { RenderTraceInvalidateEnd(layer, "FF00FF"); } break; } case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); ShadowThebesLayer* thebes = static_cast<ShadowThebesLayer*>(compositable->GetLayer()); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion); replyv.push_back( OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); break; } case CompositableOperation::TOpUpdatePictureRect: { const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); CompositableHost* compositable = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost(); MOZ_ASSERT(compositable); compositable->SetPictureRect(op.picture()); break; } default: { MOZ_ASSERT(false, "bad type"); } } return true; }
void BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer) { if (!HasShadow()) { BasicCanvasLayer::Paint(aContext, aMaskLayer); return; } if (!IsDirty()) return; if (mGLContext && !mForceReadback && BasicManager()->GetParentBackendType() == mozilla::layers::LAYERS_OPENGL) { TextureImage::TextureShareType flags; // if process type is default, then it is single-process (non-e10s) if (XRE_GetProcessType() == GeckoProcessType_Default) flags = TextureImage::ThreadShared; else flags = TextureImage::ProcessShared; SharedTextureHandle handle = GetSharedBackBufferHandle(); if (!handle) { handle = mGLContext->CreateSharedHandle(flags); if (handle) { mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size(), false); } } if (handle) { mGLContext->MakeCurrent(); mGLContext->UpdateSharedHandle(flags, handle); // call Painted() to reset our dirty 'bit' Painted(); FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), mNeedsYFlip, mBackBuffer); // Move SharedTextureHandle ownership to ShadowLayer mBackBuffer = SurfaceDescriptor(); return; } } bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE); if (!IsSurfaceDescriptorValid(mBackBuffer) || isOpaque != mBufferIsOpaque) { DestroyBackBuffer(); mBufferIsOpaque = isOpaque; gfxIntSize size(mBounds.width, mBounds.height); gfxASurface::gfxContentType type = isOpaque ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA; if (!BasicManager()->AllocBuffer(size, type, &mBackBuffer)) { NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!"); } } AutoOpenSurface autoBackSurface(OPEN_READ_WRITE, mBackBuffer); if (aMaskLayer) { static_cast<BasicImplData*>(aMaskLayer->ImplData()) ->Paint(aContext, nullptr); } UpdateSurface(autoBackSurface.Get(), nullptr); FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), mNeedsYFlip, mBackBuffer); }
virtual void DestroyFrontBuffer() { if (IsSurfaceDescriptorValid(mFrontSurface)) { mAllocator->DestroySharedSurface(&mFrontSurface); } }
bool ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) { AutoLockImage autoLock(aContainer); Image *image = autoLock.GetImage(); if (!image) { return false; } if (mLastPaintedImageSerial == image->GetSerial()) { return true; } if (image->GetFormat() == PLANAR_YCBCR) { EnsureTextureClient(TEXTURE_YCBCR); PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image); if (ycbcr->AsSharedPlanarYCbCrImage()) { AutoLockTextureClient lock(mTextureClient); SurfaceDescriptor sd; if (!ycbcr->AsSharedPlanarYCbCrImage()->ToSurfaceDescriptor(sd)) { return false; } if (IsSurfaceDescriptorValid(*lock.GetSurfaceDescriptor())) { GetForwarder()->DestroySharedSurface(lock.GetSurfaceDescriptor()); } *lock.GetSurfaceDescriptor() = sd; } else { AutoLockYCbCrClient clientLock(mTextureClient); if (!clientLock.Update(ycbcr)) { NS_WARNING("failed to update TextureClient (YCbCr)"); return false; } } } else if (image->GetFormat() == SHARED_TEXTURE) { EnsureTextureClient(TEXTURE_SHARED_GL_EXTERNAL); SharedTextureImage* sharedImage = static_cast<SharedTextureImage*>(image); const SharedTextureImage::Data *data = sharedImage->GetData(); SharedTextureDescriptor texture(data->mShareType, data->mHandle, data->mSize, data->mInverted); mTextureClient->SetDescriptor(SurfaceDescriptor(texture)); } else if (image->GetFormat() == SHARED_RGB) { EnsureTextureClient(TEXTURE_SHMEM); nsIntRect rect(0, 0, image->GetSize().width, image->GetSize().height); UpdatePictureRect(rect); AutoLockTextureClient lock(mTextureClient); SurfaceDescriptor desc; if (!static_cast<SharedRGBImage*>(image)->ToSurfaceDescriptor(desc)) { return false; } mTextureClient->SetDescriptor(desc); } else { nsRefPtr<gfxASurface> surface = image->GetAsSurface(); MOZ_ASSERT(surface); EnsureTextureClient(TEXTURE_SHMEM); nsRefPtr<gfxPattern> pattern = new gfxPattern(surface); pattern->SetFilter(mFilter); AutoLockShmemClient clientLock(mTextureClient); if (!clientLock.Update(image, aContentFlags, pattern)) { NS_WARNING("failed to update TextureClient"); return false; } } Updated(); if (image->GetFormat() == PLANAR_YCBCR) { PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(image); UpdatePictureRect(ycbcr->GetData()->GetPictureRect()); } mLastPaintedImageSerial = image->GetSerial(); aContainer->NotifyPaintedImage(image); return true; }