void
SourceSurfaceD2D1::DrawTargetWillChange()
{
  // At this point in time this should always be true here.
  MOZ_ASSERT(mRealizedBitmap);

  RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap;

  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));

  D2D1_POINT_2U point = D2D1::Point2U(0, 0);
  D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
  mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect);
  mImage = mRealizedBitmap;

  DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat);
  mDrawTarget = nullptr;

  // We now no longer depend on the source surface content remaining the same.
  MarkIndependent();
}
bool SourceSurfaceD2D1::EnsureRealizedBitmap() {
  if (mRealizedBitmap) {
    return true;
  }

  // Why aren't we using mDevice here or anywhere else?
  RefPtr<ID2D1Device> device = Factory::GetD2D1Device();
  if (!device) {
    return false;
  }

  RefPtr<ID2D1DeviceContext> dc;
  device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
                              getter_AddRefs(dc));

  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  dc->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props,
                   (ID2D1Bitmap1 **)getter_AddRefs(mRealizedBitmap));

  dc->SetTarget(mRealizedBitmap);

  dc->BeginDraw();
  dc->DrawImage(mImage);
  dc->EndDraw();

  return true;
}
Esempio n. 3
0
bool
SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
                                  SurfaceFormat aFormat,
                                  ID2D1RenderTarget *aRT)
{
  HRESULT hr;

  RefPtr<IDXGISurface> surf;

  hr = aTexture->QueryInterface((IDXGISurface**)&surf);

  if (FAILED(hr)) {
    gfxWarning() << "Failed to QI texture to surface. Code: " << hexa(hr);
    return false;
  }

  D3D10_TEXTURE2D_DESC desc;
  aTexture->GetDesc(&desc);

  mSize = IntSize(desc.Width, desc.Height);
  mFormat = aFormat;

  D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(aFormat));
  hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));

  if (FAILED(hr)) {
    gfxWarning() << "Failed to create SharedBitmap. Code: " << hexa(hr);
    return false;
  }

  aTexture->GetDevice(byRef(mDevice));
  DrawTargetD2D::mVRAMUsageSS += GetByteSize();

  return true;
}
TemporaryRef<DataSourceSurface>
SourceSurfaceD2D1::GetDataSurface()
{
  HRESULT hr;

  EnsureRealizedBitmap();

  RefPtr<ID2D1Bitmap1> softwareBitmap;
  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW |
                        D2D1_BITMAP_OPTIONS_CPU_READ;
  hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(softwareBitmap));

  if (FAILED(hr)) {
    gfxCriticalError() << "Failed to create software bitmap: " << mSize << " Code: " << hexa(hr);
    return nullptr;
  }

  D2D1_POINT_2U point = D2D1::Point2U(0, 0);
  D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
  
  hr = softwareBitmap->CopyFromBitmap(&point, mRealizedBitmap, &rect);

  if (FAILED(hr)) {
    gfxWarning() << "Failed to readback into software bitmap. Code: " << hexa(hr);
    return nullptr;
  }

  return MakeAndAddRef<DataSourceSurfaceD2D1>(softwareBitmap, mFormat);
}
Esempio n. 5
0
void
SourceSurfaceD2D1::DrawTargetWillChange()
{
  // At this point in time this should always be true here.
  MOZ_ASSERT(mRealizedBitmap);

  RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap;

  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)getter_AddRefs(mRealizedBitmap));

  if (FAILED(hr)) {
    gfxCriticalError() << "Failed to create bitmap to make DrawTarget copy. Size: " << mSize << " Code: " << hexa(hr);
    MarkIndependent();
    return;
  }

  D2D1_POINT_2U point = D2D1::Point2U(0, 0);
  D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
  mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect);
  mImage = mRealizedBitmap;

  DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat);

  // We now no longer depend on the source surface content remaining the same.
  MarkIndependent();
}
Esempio n. 6
0
TemporaryRef<SourceSurface>
DrawTargetD2D1::OptimizeSourceSurface(SourceSurface* aSurface) const
{
  if (aSurface->GetType() == SurfaceType::D2D1_1_IMAGE) {
    return aSurface;
  }

  RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();

  DataSourceSurface::MappedSurface map;
  if (!data->Map(DataSourceSurface::MapType::READ, &map)) {
    return nullptr;
  }

  RefPtr<ID2D1Bitmap1> bitmap;
  HRESULT hr = mDC->CreateBitmap(D2DIntSize(data->GetSize()), map.mData, map.mStride,
                                 D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, D2DPixelFormat(data->GetFormat())),
                                 byRef(bitmap));

  data->Unmap();

  if (!bitmap) {
    return data;
  }

  return new SourceSurfaceD2D1(bitmap.get(), mDC, data->GetFormat(), data->GetSize());
}
Esempio n. 7
0
TemporaryRef<SourceSurface>
DrawTargetD2D1::CreateSourceSurfaceFromData(unsigned char *aData,
                                            const IntSize &aSize,
                                            int32_t aStride,
                                            SurfaceFormat aFormat) const
{
  RefPtr<ID2D1Bitmap1> bitmap;

  HRESULT hr = mDC->CreateBitmap(D2DIntSize(aSize), aData, aStride,
                                 D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_NONE, D2DPixelFormat(aFormat)),
                                 byRef(bitmap));

  if (!bitmap) {
    return nullptr;
  }

  return new SourceSurfaceD2D1(bitmap.get(), mDC, aFormat, aSize);
}
TemporaryRef<DataSourceSurface>
SourceSurfaceD2D1::GetDataSurface()
{
  EnsureRealizedBitmap();

  RefPtr<ID2D1Bitmap1> softwareBitmap;
  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW |
                        D2D1_BITMAP_OPTIONS_CPU_READ;
  mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(softwareBitmap));

  D2D1_POINT_2U point = D2D1::Point2U(0, 0);
  D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
  softwareBitmap->CopyFromBitmap(&point, mRealizedBitmap, &rect);
  return new DataSourceSurfaceD2D1(softwareBitmap, mFormat);
}
Esempio n. 9
0
bool
SourceSurfaceD2D::InitFromData(unsigned char *aData,
                               const IntSize &aSize,
                               int32_t aStride,
                               SurfaceFormat aFormat,
                               ID2D1RenderTarget *aRT)
{
  HRESULT hr;

  mFormat = aFormat;
  mSize = aSize;

  if ((uint32_t)aSize.width > aRT->GetMaximumBitmapSize() ||
      (uint32_t)aSize.height > aRT->GetMaximumBitmapSize()) {
    gfxDebug() << "Bitmap does not fit in texture.";
    return false;
  }

  D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(aFormat));
  hr = aRT->CreateBitmap(D2DIntSize(aSize), props, byRef(mBitmap));

  if (FAILED(hr)) {
    gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hexa(hr);
    return false;
  }

  hr = mBitmap->CopyFromMemory(nullptr, aData, aStride);

  if (FAILED(hr)) {
    gfxWarning() << "Failed to copy data to D2D bitmap. Code: " << hexa(hr);
    return false;
  }

  DrawTargetD2D::mVRAMUsageSS += GetByteSize();
  mDevice = Factory::GetDirect3D10Device();

  return true;
}
Esempio n. 10
0
void
SourceSurfaceD2D1::EnsureRealizedBitmap()
{
  if (mRealizedBitmap) {
    return;
  }

  RefPtr<ID2D1DeviceContext> dc;
  Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, byRef(dc));

  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(mFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  dc->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));

  dc->SetTarget(mRealizedBitmap);

  dc->BeginDraw();
  dc->DrawImage(mImage);
  dc->EndDraw();
}
Esempio n. 11
0
bool
DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
{
  HRESULT hr;
  
  hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));

  if (FAILED(hr)) {
    gfxWarning() << *this << ": Error " << hr << " failed to initialize new DeviceContext.";
    return false;
  }

  D2D1_BITMAP_PROPERTIES1 props;
  props.dpiX = 96;
  props.dpiY = 96;
  props.pixelFormat = D2DPixelFormat(aFormat);
  props.colorContext = nullptr;
  props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
  mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mBitmap));

  if (FAILED(hr)) {
    gfxWarning() << *this << ": Error " << hr << " failed to create new CommandList.";
    return false;
  }

  mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mTempBitmap));

  mDC->SetTarget(mBitmap);

  mDC->BeginDraw();

  mFormat = aFormat;
  mSize = aSize;

  return true;
}
ID2D1Bitmap*
SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
{
  if (mBitmap) {
    return mBitmap;
  }

  HRESULT hr;
  D3D10_TEXTURE2D_DESC desc;
  mTexture->GetDesc(&desc);

  IntSize size(desc.Width, desc.Height);
  
  RefPtr<IDXGISurface> surf;
  hr = mTexture->QueryInterface((IDXGISurface**)byRef(surf));

  if (FAILED(hr)) {
    gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hr;
    return nullptr;
  }

  D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(mFormat));
  hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));

  if (FAILED(hr)) {
    // This seems to happen for FORMAT_A8 sometimes...
    hr = aRT->CreateBitmap(D2D1::SizeU(desc.Width, desc.Height),
                           D2D1::BitmapProperties(D2DPixelFormat(mFormat)),
                           byRef(mBitmap));

    if (FAILED(hr)) {
      gfxWarning() << "Failed in CreateBitmap. Code: " << hr;
      return nullptr;
    }

    RefPtr<ID2D1RenderTarget> rt;

    if (mDrawTarget) {
      rt = mDrawTarget->mRT;
    }

    if (!rt) {
      // Okay, we already separated from our drawtarget. And we're an A8
      // surface the only way we can get to a bitmap is by creating a
      // a rendertarget and from there copying to a bitmap! Terrible!
      RefPtr<IDXGISurface> surface;

      hr = mTexture->QueryInterface((IDXGISurface**)byRef(surface));

      if (FAILED(hr)) {
        gfxWarning() << "Failed to QI texture to surface.";
        return nullptr;
      }

      D2D1_RENDER_TARGET_PROPERTIES props =
        D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2DPixelFormat(mFormat));
      hr = DrawTargetD2D::factory()->CreateDxgiSurfaceRenderTarget(surface, props, byRef(rt));

      if (FAILED(hr)) {
        gfxWarning() << "Failed to create D2D render target for texture.";
        return nullptr;
      }
    }

    mBitmap->CopyFromRenderTarget(nullptr, rt, nullptr);
    return mBitmap;
  }

  return mBitmap;
}