Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
			}
		}
	}
}