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(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat))); hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap)); if (FAILED(hr)) { gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr; return false; } DrawTargetD2D::mVRAMUsageSS += GetByteSize(); mDevice = Factory::GetDirect3D10Device(); 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; 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; }
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()); }
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; }
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); }
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(); }