void MainWindow::plotData() { // Get shared access (read only). boost::shared_ptr < boost::shared_mutex > mutexX = _xData->getMutex(); boost::shared_lock < boost::shared_mutex > lockX (*mutexX.get()); boost::shared_ptr < boost::shared_mutex > mutexY = _yData->getMutex(); boost::shared_lock < boost::shared_mutex > lockY (*mutexY.get()); _xMin = std::numeric_limits<double>::max(); _yMin = std::numeric_limits<double>::max(); _xMax = std::numeric_limits<double>::min(); _yMax = std::numeric_limits<double>::min(); for(int n = 0; n < _xData->getData().size(); ++n) { _xMin = qMin(_xMin, _xData->getData()[n]); _xMax = qMax(_xMax, _xData->getData()[n]); _yMin = qMin(_yMin, _yData->getData()[n]); _yMax = qMax(_yMax, _yData->getData()[n]); } _yMax = pow(10, ceil(log10(_yMax))); // give the axes some labels: ui->customPlot->graph(0)->setData(_xData->getData(), _yData->getData()); // set axes ranges, so we see all data: ui->customPlot->xAxis->setRange(_xMin, _xMax); ui->customPlot->yAxis->setRange(_yMin, _yMax); ui->customPlot->replot(); }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(); if (!device || aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device(); if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) { return GetD3D9TextureClient(aClient); } return nullptr; } if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(byRef(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } RefPtr<IDXGIResource> resource; HANDLE shareHandleY; textureY->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleY); HANDLE shareHandleCb; textureCb->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCb); HANDLE shareHandleCr; textureCr->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCr); mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, shareHandleY, shareHandleCb, shareHandleCr, GetSize(), mData.mYSize, mData.mCbCrSize); return mTextureClient; }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11Device> device; gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device); LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType(); if (!device || backend != LayersBackend::LAYERS_D3D11) { if (backend == LayersBackend::LAYERS_D3D9 || backend == LayersBackend::LAYERS_D3D11) { return GetD3D9TextureClient(aClient); } return nullptr; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(getter_AddRefs(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } mTextureClient = TextureClient::CreateWithData( DXGIYCbCrTextureData::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, GetSize(), mData.mYSize, mData.mCbCrSize), TextureFlags::DEFAULT, aClient->GetForwarder() ); return mTextureClient; }
DXGIYCbCrTextureData* IMFYCbCrImage::GetD3D11TextureData(Data aData, gfx::IntSize aSize) { HRESULT hr; RefPtr<ID3D10Multithread> mt; RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetContentDevice(); if (!device) { device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); } hr = device->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); if (FAILED(hr)) { return nullptr; } if (!mt->GetMultithreadProtected()) { return nullptr; } if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) { return nullptr; } if (aData.mYStride < 0 || aData.mCbCrStride < 0) { // D3D11 only supports unsigned stride values. return nullptr; } CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, aData.mYSize.width, aData.mYSize.height, 1, 1); if (device == gfx::DeviceManagerDx::Get()->GetCompositorDevice()) { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; } else { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; } RefPtr<ID3D11Texture2D> textureY; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = aData.mCbCrSize.width; newDesc.Height = aData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); // The documentation here seems to suggest using the immediate mode context // on more than one thread is not allowed: // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476891(v=vs.85).aspx // The Debug Layer seems to imply it is though. When the ID3D10Multithread // layer is on. The Enter/Leave of the critical section shouldn't even be // required but were added for extra security. { AutoLockTexture lockY(textureY); AutoLockTexture lockCr(textureCr); AutoLockTexture lockCb(textureCb); mt->Enter(); RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext((ID3D11DeviceContext**)getter_AddRefs(ctx)); D3D11_BOX box; box.front = box.top = box.left = 0; box.back = 1; box.right = aData.mYSize.width; box.bottom = aData.mYSize.height; ctx->UpdateSubresource(textureY, 0, &box, aData.mYChannel, aData.mYStride, 0); box.right = aData.mCbCrSize.width; box.bottom = aData.mCbCrSize.height; ctx->UpdateSubresource(textureCb, 0, &box, aData.mCbChannel, aData.mCbCrStride, 0); ctx->UpdateSubresource(textureCr, 0, &box, aData.mCrChannel, aData.mCbCrStride, 0); mt->Leave(); } return DXGIYCbCrTextureData::Create(TextureFlags::DEFAULT, textureY, textureCb, textureCr, aSize, aData.mYSize, aData.mCbCrSize); }
bool D3D11YCbCrImage::SetData(KnowsCompositor* aAllocator, ImageContainer* aContainer, const PlanarYCbCrData& aData) { mPictureRect = IntRect( aData.mPicX, aData.mPicY, aData.mPicSize.width, aData.mPicSize.height); mYSize = aData.mYSize; mCbCrSize = aData.mCbCrSize; mColorSpace = aData.mYUVColorSpace; D3D11YCbCrRecycleAllocator* allocator = aContainer->GetD3D11YCbCrRecycleAllocator(aAllocator); if (!allocator) { return false; } allocator->SetSizes(aData.mYSize, aData.mCbCrSize); mTextureClient = allocator->CreateOrRecycle(SurfaceFormat::A8, mYSize, BackendSelector::Content, TextureFlags::DEFAULT); if (!mTextureClient) { return false; } DXGIYCbCrTextureData *data = static_cast<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData()); ID3D11Texture2D* textureY = data->GetD3D11Texture(0); ID3D11Texture2D* textureCb = data->GetD3D11Texture(1); ID3D11Texture2D* textureCr = data->GetD3D11Texture(2); RefPtr<ID3D10Multithread> mt; HRESULT hr = allocator->GetDevice()->QueryInterface( (ID3D10Multithread**)getter_AddRefs(mt)); if (FAILED(hr) || !mt) { gfxCriticalError() << "Multithread safety interface not supported. " << hr; return false; } if (!mt->GetMultithreadProtected()) { gfxCriticalError() << "Device used not marked as multithread-safe."; return false; } D3D11MTAutoEnter mtAutoEnter(mt.forget()); RefPtr<ID3D11DeviceContext> ctx; allocator->GetDevice()->GetImmediateContext(getter_AddRefs(ctx)); AutoLockD3D11Texture lockY(textureY); AutoLockD3D11Texture lockCb(textureCb); AutoLockD3D11Texture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, aData.mYChannel, aData.mYStride, aData.mYStride * aData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, aData.mCbChannel, aData.mCbCrStride, aData.mCbCrStride * aData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, aData.mCrChannel, aData.mCbCrStride, aData.mCbCrStride * aData.mCbCrSize.height); return true; }
already_AddRefed<SourceSurface> D3D11YCbCrImage::GetAsSourceSurface() { if (!mTextureClient) { gfxWarning() << "GetAsSourceSurface() called on uninitialized D3D11YCbCrImage."; return nullptr; } gfx::IntSize size(mPictureRect.Size()); gfx::SurfaceFormat format = gfx::ImageFormatToSurfaceFormat(gfxVars::OffscreenFormat()); HRESULT hr; PlanarYCbCrData data; DXGIYCbCrTextureData *dxgiData = static_cast<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData()); if (!dxgiData) { gfxCriticalError() << "Failed to get texture client internal data."; return nullptr; } RefPtr<ID3D11Texture2D> texY = dxgiData->GetD3D11Texture(0); RefPtr<ID3D11Texture2D> texCb = dxgiData->GetD3D11Texture(1); RefPtr<ID3D11Texture2D> texCr = dxgiData->GetD3D11Texture(2); RefPtr<ID3D11Texture2D> softTexY, softTexCb, softTexCr; D3D11_TEXTURE2D_DESC desc; RefPtr<ID3D11Device> dev; texY->GetDevice(getter_AddRefs(dev)); RefPtr<ID3D10Multithread> mt; hr = dev->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); if (FAILED(hr) || !mt) { gfxCriticalError() << "Multithread safety interface not supported."; return nullptr; } if (!mt->GetMultithreadProtected()) { gfxCriticalError() << "Device used not marked as multithread-safe."; return nullptr; } D3D11MTAutoEnter mtAutoEnter(mt.forget()); texY->GetDesc(&desc); desc.BindFlags = 0; desc.MiscFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; dev->CreateTexture2D(&desc, nullptr, getter_AddRefs(softTexY)); texCb->GetDesc(&desc); desc.BindFlags = 0; desc.MiscFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; dev->CreateTexture2D(&desc, nullptr, getter_AddRefs(softTexCb)); dev->CreateTexture2D(&desc, nullptr, getter_AddRefs(softTexCr)); RefPtr<ID3D11DeviceContext> ctx; dev->GetImmediateContext(getter_AddRefs(ctx)); { AutoLockD3D11Texture lockY(texY); AutoLockD3D11Texture lockCb(texCb); AutoLockD3D11Texture lockCr(texCr); ctx->CopyResource(softTexY, texY); ctx->CopyResource(softTexCb, texCb); ctx->CopyResource(softTexCr, texCr); } D3D11_MAPPED_SUBRESOURCE mapY, mapCb, mapCr; RefPtr<gfx::DataSourceSurface> surface; mapY.pData = mapCb.pData = mapCr.pData = nullptr; hr = ctx->Map(softTexY, 0, D3D11_MAP_READ, 0, &mapY); if (FAILED(hr)) { gfxCriticalError() << "Failed to map Y plane (" << hr << ")"; return nullptr; } hr = ctx->Map(softTexCb, 0, D3D11_MAP_READ, 0, &mapCb); if (FAILED(hr)) { gfxCriticalError() << "Failed to map Y plane (" << hr << ")"; return nullptr; } hr = ctx->Map(softTexCr, 0, D3D11_MAP_READ, 0, &mapCr); if (FAILED(hr)) { gfxCriticalError() << "Failed to map Y plane (" << hr << ")"; return nullptr; } MOZ_ASSERT(mapCb.RowPitch == mapCr.RowPitch); data.mPicX = mPictureRect.x; data.mPicY = mPictureRect.y; data.mPicSize = mPictureRect.Size(); data.mStereoMode = StereoMode::MONO; data.mYUVColorSpace = mColorSpace; data.mYSkip = data.mCbSkip = data.mCrSkip = 0; data.mYSize = mYSize; data.mCbCrSize = mCbCrSize; data.mYChannel = static_cast<uint8_t*>(mapY.pData); data.mYStride = mapY.RowPitch; data.mCbChannel = static_cast<uint8_t*>(mapCb.pData); data.mCrChannel = static_cast<uint8_t*>(mapCr.pData); data.mCbCrStride = mapCb.RowPitch; gfx::GetYCbCrToRGBDestFormatAndSize(data, format, size); if (size.width > PlanarYCbCrImage::MAX_DIMENSION || size.height > PlanarYCbCrImage::MAX_DIMENSION) { gfxCriticalError() << "Illegal image dest width or height"; return nullptr; } surface = gfx::Factory::CreateDataSourceSurface(size, format); if (!surface) { gfxCriticalError() << "Failed to create DataSourceSurface for image: " << size << " " << format; return nullptr; } DataSourceSurface::ScopedMap mapping(surface, DataSourceSurface::WRITE); if (!mapping.IsMapped()) { gfxCriticalError() << "Failed to map DataSourceSurface for D3D11YCbCrImage"; return nullptr; } gfx::ConvertYCbCrToRGB( data, format, size, mapping.GetData(), mapping.GetStride()); ctx->Unmap(softTexY, 0); ctx->Unmap(softTexCb, 0); ctx->Unmap(softTexCr, 0); return surface.forget(); }
AxisLock::AxisLock(bool x, bool y, bool z) : lock_x(false), lock_y(false), lock_z(false) { if(x) lockX(0); if(y) lockY(0); if(z) lockZ(0); }