void CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { if (mFront) { mPrevFront = mFront; mFront = nullptr; } auto gl = aLayer->mGLContext; gl->MakeCurrent(); if (aLayer->mGLFrontbuffer) { mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get()); if (mFront) mFront->Surf()->Fence(); } else { mFront = gl->Screen()->Front(); if (!mFront) return; } MOZ_ASSERT(mFront); // Alright, now sort out the IPC goop. SharedSurface* surf = mFront->Surf(); auto forwarder = GetForwarder(); auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE; // Get a TexClient from our surf. RefPtr<TextureClient> newTex = TexClientFromShSurf(surf, flags); if (!newTex) { auto manager = aLayer->ClientManager(); auto shadowForwarder = manager->AsShadowForwarder(); auto layersBackend = shadowForwarder->GetCompositorBackendType(); newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend); } MOZ_ASSERT(newTex); // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(newTex) ); // Remove the old TexClient. if (mFrontTex) { // remove old buffer from CompositableHost RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker(); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontTex); mFrontTex->SetRemoveFromCompositableTracker(tracker); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontTex); mFrontTex = nullptr; } // Use the new TexClient. mFrontTex = newTex; forwarder->UpdatedTexture(this, mFrontTex, nullptr); forwarder->UseTexture(this, mFrontTex); }
void CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer) { GLContext* gl = nullptr; ClientCanvasLayer* layer = nullptr; AsyncCanvasRenderer* asyncRenderer = nullptr; if (aRenderer.constructed<ClientCanvasLayer*>()) { layer = aRenderer.ref<ClientCanvasLayer*>(); gl = layer->mGLContext; } else { asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>(); gl = asyncRenderer->mGLContext; } gl->MakeCurrent(); RefPtr<TextureClient> newFront; if (layer && layer->mGLFrontbuffer) { mShSurfClient = CloneSurface(layer->mGLFrontbuffer.get(), layer->mFactory.get()); if (!mShSurfClient) { gfxCriticalError() << "Invalid canvas front buffer"; return; } } else { mShSurfClient = gl->Screen()->Front(); if (!mShSurfClient) { return; } } MOZ_ASSERT(mShSurfClient); newFront = mShSurfClient; SharedSurface* surf = mShSurfClient->Surf(); // Readback if needed. mReadbackClient = nullptr; auto forwarder = GetForwarder(); bool needsReadback = (surf->mType == SharedSurfaceType::Basic); if (needsReadback) { TextureFlags flags = TextureFlags::IMMUTABLE; CompositableForwarder* shadowForwarder = nullptr; if (layer) { flags |= layer->Flags(); shadowForwarder = layer->ClientManager()->AsShadowForwarder(); } else { MOZ_ASSERT(asyncRenderer); flags |= mTextureFlags; shadowForwarder = GetForwarder(); } auto layersBackend = shadowForwarder->GetCompositorBackendType(); mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend); if (asyncRenderer) { // Above codes will readback the GLContext to mReadbackClient // in order to send frame to compositor. We copy from this // TextureClient directly by calling CopyFromTextureClient(). // Therefore, if main-thread want the content of GLContext, // it don't have to readback it again. asyncRenderer->CopyFromTextureClient(mReadbackClient); } newFront = mReadbackClient; } else { mReadbackClient = nullptr; } MOZ_ASSERT(newFront); if (!newFront) { // May happen in a release build in case of memory pressure. gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize; return; } mNewFront = newFront; }
void CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { auto gl = aLayer->mGLContext; gl->MakeCurrent(); RefPtr<TextureClient> newFront; if (aLayer->mGLFrontbuffer) { mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get()); if (!mShSurfClient) { gfxCriticalError() << "Invalid canvas front buffer"; return; } } else { mShSurfClient = gl->Screen()->Front(); if (!mShSurfClient) { return; } } MOZ_ASSERT(mShSurfClient); newFront = mShSurfClient; SharedSurface* surf = mShSurfClient->Surf(); // Readback if needed. mReadbackClient = nullptr; auto forwarder = GetForwarder(); bool needsReadback = (surf->mType == SharedSurfaceType::Basic); if (needsReadback) { TextureFlags flags = aLayer->Flags() | TextureFlags::IMMUTABLE; auto manager = aLayer->ClientManager(); auto shadowForwarder = manager->AsShadowForwarder(); auto layersBackend = shadowForwarder->GetCompositorBackendType(); mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend); newFront = mReadbackClient; } else { mReadbackClient = nullptr; } MOZ_ASSERT(newFront); if (!newFront) { // May happen in a release build in case of memory pressure. gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize; return; } if (mFront) { if (mFront->GetFlags() & TextureFlags::RECYCLE) { mFront->WaitForCompositorRecycle(); } } mFront = newFront; // Add the new TexClient. MOZ_ALWAYS_TRUE( AddTextureClient(mFront) ); forwarder->UseTexture(this, mFront); }
void Fur( mapDrawSurface_t *ds ) { int i, j, k, numLayers; float offset, fade, a; mapDrawSurface_t *fur; bspDrawVert_t *dv; /* dummy check */ if( ds == NULL || ds->fur || ds->shaderInfo->furNumLayers < 1 ) return; /* get basic info */ numLayers = ds->shaderInfo->furNumLayers; offset = ds->shaderInfo->furOffset; fade = ds->shaderInfo->furFade * 255.0f; /* debug code */ //% Sys_FPrintf( SYS_VRB, "Fur(): layers: %d offset: %f fade: %f %s\n", //% numLayers, offset, fade, ds->shaderInfo->shader ); /* initial offset */ for( j = 0; j < ds->numVerts; j++ ) { /* get surface vert */ dv = &ds->verts[ j ]; /* offset is scaled by original vertex alpha */ a = (float) dv->color[ 0 ][ 3 ] / 255.0; /* offset it */ VectorMA( dv->xyz, (offset * a), dv->normal, dv->xyz ); } /* wash, rinse, repeat */ for( i = 1; i < numLayers; i++ ) { /* clone the surface */ fur = CloneSurface( ds, ds->shaderInfo ); if( fur == NULL ) return; /* set it to fur */ fur->fur = qtrue; /* walk the verts */ for( j = 0; j < fur->numVerts; j++ ) { /* get surface vert */ dv = &ds->verts[ j ]; /* offset is scaled by original vertex alpha */ a = (float) dv->color[ 0 ][ 3 ] / 255.0; /* get fur vert */ dv = &fur->verts[ j ]; /* offset it */ VectorMA( dv->xyz, (offset * a * i), dv->normal, dv->xyz ); /* fade alpha */ for( k = 0; k < MAX_LIGHTMAPS; k++ ) { a = (float) dv->color[ k ][ 3 ] - fade; if( a > 255.0f ) dv->color[ k ][ 3 ] = 255; else if( a < 0 ) dv->color[ k ][ 3 ] = 0; else dv->color[ k ][ 3 ] = a; } } } }