void
ShareableCanvasRenderer::UpdateCompositableClient()
{
  if (!CreateCompositable()) {
    return;
  }

  if (mCanvasClient && mAsyncRenderer) {
    mCanvasClient->UpdateAsync(mAsyncRenderer);
  }

  if (!IsDirty()) {
    return;
  }
  ResetDirty();

  FirePreTransactionCallback();
  if (mBufferProvider && mBufferProvider->GetTextureClient()) {
    if (!mBufferProvider->SetKnowsCompositor(GetForwarder())) {
      gfxCriticalNote << "BufferProvider::SetForwarder failed";
      return;
    }
    mCanvasClient->UpdateFromTexture(mBufferProvider->GetTextureClient());
  } else {
    mCanvasClient->Update(gfx::IntSize(mSize.width, mSize.height), this);
  }

  FireDidTransactionCallback();

  mCanvasClient->Updated();
}
예제 #2
0
void
ClientCanvasLayer::RenderLayer()
{
    PROFILER_LABEL("ClientCanvasLayer", "RenderLayer",
                   js::ProfileEntry::Category::GRAPHICS);

    RenderMaskLayers(this);

    if (!mCanvasClient) {
        TextureFlags flags = TextureFlags::IMMEDIATE_UPLOAD;
        if (mOriginPos == gl::OriginPos::BottomLeft) {
            flags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
        }

        if (!mGLContext) {
            // We don't support locking for buffer surfaces currently
            flags |= TextureFlags::IMMEDIATE_UPLOAD;
        }

        if (!mIsAlphaPremultiplied) {
            flags |= TextureFlags::NON_PREMULTIPLIED;
        }

        mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
                        ClientManager()->AsShadowForwarder(),
                        flags);
        if (!mCanvasClient) {
            return;
        }
        if (HasShadow()) {
            if (mAsyncRenderer) {
                static_cast<CanvasClientBridge*>(mCanvasClient.get())->SetLayer(this);
            } else {
                mCanvasClient->Connect();
                ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this);
            }
        }
    }

    if (mCanvasClient && mAsyncRenderer) {
        mCanvasClient->UpdateAsync(mAsyncRenderer);
    }

    if (!IsDirty()) {
        return;
    }
    Painted();

    FirePreTransactionCallback();
    if (mBufferProvider && mBufferProvider->GetTextureClient()) {
        mCanvasClient->UpdateFromTexture(mBufferProvider->GetTextureClient());
    } else {
        mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
    }

    FireDidTransactionCallback();

    ClientManager()->Hold(this);
    mCanvasClient->Updated();
}
예제 #3
0
void
BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
{
  if (IsHidden())
    return;
  UpdateSurface();
  FireDidTransactionCallback();
  PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer);
}
예제 #4
0
void
ClientCanvasLayer::RenderLayer()
{
  PROFILER_LABEL("ClientCanvasLayer", "RenderLayer",
    js::ProfileEntry::Category::GRAPHICS);

  if (GetMaskLayer()) {
    ToClientLayer(GetMaskLayer())->RenderLayer();
  }

  if (!IsDirty()) {
    return;
  }

  if (!mCanvasClient) {
    TextureFlags flags = TextureFlags::IMMEDIATE_UPLOAD;
    if (mNeedsYFlip) {
      flags |= TextureFlags::NEEDS_Y_FLIP;
    }

    if (!mGLContext) {
      // We don't support locking for buffer surfaces currently
      flags |= TextureFlags::IMMEDIATE_UPLOAD;
    } else {
      // GLContext's SurfaceStream handles ownership itself,
      // and doesn't require layers to do any deallocation.
      flags |= TextureFlags::DEALLOCATE_CLIENT;
    }

    if (!mIsAlphaPremultiplied) {
      flags |= TextureFlags::NON_PREMULTIPLIED;
    }

    mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
                                                     ClientManager()->AsShadowForwarder(),
                                                     flags);
    if (!mCanvasClient) {
      return;
    }
    if (HasShadow()) {
      mCanvasClient->Connect();
      ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this);
    }
  }

  FirePreTransactionCallback();
  mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);

  FireDidTransactionCallback();

  ClientManager()->Hold(this);
  mCanvasClient->Updated();
  mCanvasClient->OnTransaction();
}
예제 #5
0
void
CanvasLayerD3D9::RenderLayer()
{
  FirePreTransactionCallback();
  UpdateSurface();
  if (mD3DManager->CompositingDisabled()) {
    return;
  }
  FireDidTransactionCallback();

  if (!mTexture)
    return;

  /*
   * We flip the Y axis here, note we can only do this because we are in
   * CULL_NONE mode!
   */
  ShaderConstantRect quad(0, 0, mBounds.width, mBounds.height);

  const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
  if (needsYFlip) {
    quad.mHeight = (float)-mBounds.height;
    quad.mY = (float)mBounds.height;
  }

  device()->SetVertexShaderConstantF(CBvLayerQuad, quad, 1);

  SetShaderTransformAndOpacity();

  if (mHasAlpha) {
    mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, GetMaskLayer());
  } else {
    mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER, GetMaskLayer());
  }

  if (mFilter == GraphicsFilter::FILTER_NEAREST) {
    device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
    device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
  }
  if (!mDataIsPremultiplied) {
    device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
  }
  device()->SetTexture(0, mTexture);
  device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
  if (!mDataIsPremultiplied) {
    device()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
    device()->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
  }
  if (mFilter == GraphicsFilter::FILTER_NEAREST) {
    device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  }
}
예제 #6
0
void
CanvasLayerD3D10::RenderLayer()
{
  FirePreTransactionCallback();
  UpdateSurface();
  FireDidTransactionCallback();

  if (!mTexture)
    return;

  nsIntRect visibleRect = mVisibleRegion.GetBounds();

  SetEffectTransformAndOpacity();

  uint8_t shaderFlags = 0;
  shaderFlags |= LoadMaskTexture();
  shaderFlags |= mDataIsPremultiplied
                ? SHADER_PREMUL : SHADER_NON_PREMUL | SHADER_RGBA;
  shaderFlags |= mHasAlpha ? SHADER_RGBA : SHADER_RGB;
  shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
                ? SHADER_POINT : SHADER_LINEAR;
  ID3D10EffectTechnique* technique = SelectShader(shaderFlags);

  if (mSRView) {
    effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
  }

  effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
    ShaderConstantRectD3D10(
      (float)mBounds.x,
      (float)mBounds.y,
      (float)mBounds.width,
      (float)mBounds.height)
    );

  if (mNeedsYFlip) {
    effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
      ShaderConstantRectD3D10(
        0,
        1.0f,
        1.0f,
        -1.0f)
      );
  }

  technique->GetPassByIndex(0)->Apply(0);
  device()->Draw(4, 0);

  if (mNeedsYFlip) {
    effect()->GetVariableByName("vTextureCoords")->AsVector()->
      SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
  }
}
예제 #7
0
void
BasicCanvasLayer::Paint(DrawTarget* aTarget, SourceSurface* aMaskSurface)
{
  if (IsHidden())
    return;

  FirePreTransactionCallback();
  UpdateTarget();
  FireDidTransactionCallback();

  CompositionOp mixBlendMode = GetEffectiveMixBlendMode();
  PaintWithOpacity(aTarget,
                   GetEffectiveOpacity(),
                   aMaskSurface,
                   mixBlendMode != CompositionOp::OP_OVER ? mixBlendMode : GetOperator());
}
void
ClientCanvasLayer::RenderLayer()
{
    PROFILER_LABEL("ClientCanvasLayer", "Paint");
    if (!IsDirty()) {
        return;
    }

    if (GetMaskLayer()) {
        ToClientLayer(GetMaskLayer())->RenderLayer();
    }

    if (!mCanvasClient) {
        TextureFlags flags = TEXTURE_IMMEDIATE_UPLOAD;
        if (mNeedsYFlip) {
            flags |= TEXTURE_NEEDS_Y_FLIP;
        }

        bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
        //Append TEXTURE_DEALLOCATE_CLIENT flag for streaming buffer under OOPC case
        if (isCrossProcess && mGLContext) {
            GLScreenBuffer* screen = mGLContext->Screen();
            if (screen && screen->Stream()) {
                flags |= TEXTURE_DEALLOCATE_CLIENT;
            }
        }
        mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
                        ClientManager(), flags);
        if (!mCanvasClient) {
            return;
        }
        if (HasShadow()) {
            mCanvasClient->Connect();
            ClientManager()->Attach(mCanvasClient, this);
        }
    }

    FirePreTransactionCallback();
    mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);

    FireDidTransactionCallback();

    ClientManager()->Hold(this);
    mCanvasClient->Updated();
    mCanvasClient->OnTransaction();
}
예제 #9
0
void
BasicCanvasLayer::DeprecatedPaint(gfxContext* aContext, Layer* aMaskLayer)
{
  if (IsHidden())
    return;

  FirePreTransactionCallback();
  DeprecatedUpdateSurface();
  FireDidTransactionCallback();

  gfxContext::GraphicsOperator mixBlendMode = DeprecatedGetEffectiveMixBlendMode();
  DeprecatedPaintWithOpacity(aContext,
                             GetEffectiveOpacity(),
                             aMaskLayer,
                             mixBlendMode != gfxContext::OPERATOR_OVER ?
                               mixBlendMode :
                               DeprecatedGetOperator());
}
예제 #10
0
void
BasicCanvasLayer::Paint(DrawTarget* aDT,
                        const Point& aDeviceOffset,
                        Layer* aMaskLayer)
{
  if (IsHidden())
    return;

  if (IsDirty()) {
    Painted();

    FirePreTransactionCallback();
    UpdateTarget();
    FireDidTransactionCallback();
  }

  if (!mSurface) {
    return;
  }

  const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);

  Matrix oldTM;
  if (needsYFlip) {
    oldTM = aDT->GetTransform();
    aDT->SetTransform(Matrix(oldTM).
                        PreTranslate(0.0f, mBounds.height).
                        PreScale(1.0f, -1.0f));
  }

  FillRectWithMask(aDT, aDeviceOffset,
                   Rect(0, 0, mBounds.width, mBounds.height),
                   mSurface, ToFilter(mFilter),
                   DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
                   aMaskLayer);

  if (needsYFlip) {
    aDT->SetTransform(oldTM);
  }
}
예제 #11
0
void
CanvasLayerD3D10::RenderLayer()
{
  UpdateSurface();
  FireDidTransactionCallback();

  if (!mTexture)
    return;

  nsIntRect visibleRect = mVisibleRegion.GetBounds();

  SetEffectTransformAndOpacity();

  ID3D10EffectTechnique *technique;

  if (mDataIsPremultiplied) {
    if (!mHasAlpha) {
      if (mFilter == gfxPattern::FILTER_NEAREST) {
        technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
      } else {
        technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
      }
    } else {
      if (mFilter == gfxPattern::FILTER_NEAREST) {
        technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
      } else {
        technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
      }
    }
  } else {
    if (mFilter == gfxPattern::FILTER_NEAREST) {
      technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
    } else {
      technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
    }
  }

  if (mSRView) {
    effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);
  }

  effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
    ShaderConstantRectD3D10(
      (float)mBounds.x,
      (float)mBounds.y,
      (float)mBounds.width,
      (float)mBounds.height)
    );

  if (mNeedsYFlip) {
    effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
      ShaderConstantRectD3D10(
        0,
        1.0f,
        1.0f,
        -1.0f)
      );
  }

  technique->GetPassByIndex(0)->Apply(0);
  device()->Draw(4, 0);

  if (mNeedsYFlip) {
    effect()->GetVariableByName("vTextureCoords")->AsVector()->
      SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
  }
}
예제 #12
0
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);
}