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; }
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); }
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(); }
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()); }
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); }
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; }
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(); }
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; }