gfx/layers/d3d10/ImageLayerD3D10.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "ImageLayerD3D10.h"
michael@0 7 #include "gfxD2DSurface.h"
michael@0 8 #include "gfxWindowsSurface.h"
michael@0 9 #include "yuv_convert.h"
michael@0 10 #include "../d3d9/Nv3DVUtils.h"
michael@0 11 #include "D3D9SurfaceImage.h"
michael@0 12 #include "mozilla/gfx/Point.h"
michael@0 13 #include "gfx2DGlue.h"
michael@0 14
michael@0 15 #include "gfxWindowsPlatform.h"
michael@0 16
michael@0 17 using namespace mozilla::gfx;
michael@0 18
michael@0 19 namespace mozilla {
michael@0 20 namespace layers {
michael@0 21
michael@0 22 static already_AddRefed<ID3D10Texture2D>
michael@0 23 DataToTexture(ID3D10Device *aDevice,
michael@0 24 unsigned char *data,
michael@0 25 int stride,
michael@0 26 const IntSize &aSize)
michael@0 27 {
michael@0 28 D3D10_SUBRESOURCE_DATA srdata;
michael@0 29
michael@0 30 CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
michael@0 31 aSize.width,
michael@0 32 aSize.height,
michael@0 33 1, 1);
michael@0 34 desc.Usage = D3D10_USAGE_IMMUTABLE;
michael@0 35
michael@0 36 srdata.pSysMem = data;
michael@0 37 srdata.SysMemPitch = stride;
michael@0 38
michael@0 39 nsRefPtr<ID3D10Texture2D> texture;
michael@0 40 HRESULT hr = aDevice->CreateTexture2D(&desc, &srdata, getter_AddRefs(texture));
michael@0 41
michael@0 42 if (FAILED(hr)) {
michael@0 43 LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("Failed to create texture for data"),
michael@0 44 hr);
michael@0 45 }
michael@0 46
michael@0 47 return texture.forget();
michael@0 48 }
michael@0 49
michael@0 50 static already_AddRefed<ID3D10Texture2D>
michael@0 51 SurfaceToTexture(ID3D10Device *aDevice,
michael@0 52 SourceSurface *aSurface,
michael@0 53 const IntSize &aSize)
michael@0 54 {
michael@0 55 if (!aSurface) {
michael@0 56 return nullptr;
michael@0 57 }
michael@0 58
michael@0 59 void *nativeSurf =
michael@0 60 aSurface->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE);
michael@0 61 if (nativeSurf) {
michael@0 62 nsRefPtr<ID3D10Texture2D> texture =
michael@0 63 static_cast<ID3D10Texture2D*>(nativeSurf);
michael@0 64 ID3D10Device *dev;
michael@0 65 texture->GetDevice(&dev);
michael@0 66 if (dev == aDevice) {
michael@0 67 return texture.forget();
michael@0 68 }
michael@0 69 }
michael@0 70 RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
michael@0 71 if (!dataSurface) {
michael@0 72 return nullptr;
michael@0 73 }
michael@0 74 DataSourceSurface::MappedSurface map;
michael@0 75 if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
michael@0 76 return nullptr;
michael@0 77 }
michael@0 78 nsRefPtr<ID3D10Texture2D> texture =
michael@0 79 DataToTexture(aDevice, map.mData, map.mStride, aSize);
michael@0 80 dataSurface->Unmap();
michael@0 81 return texture.forget();
michael@0 82 }
michael@0 83
michael@0 84 Layer*
michael@0 85 ImageLayerD3D10::GetLayer()
michael@0 86 {
michael@0 87 return this;
michael@0 88 }
michael@0 89
michael@0 90 /**
michael@0 91 * Returns a shader resource view for a Cairo or remote image.
michael@0 92 * Returns nullptr if unsuccessful.
michael@0 93 * If successful, aHasAlpha will be true iff the resulting texture
michael@0 94 * has an alpha component.
michael@0 95 */
michael@0 96 ID3D10ShaderResourceView*
michael@0 97 ImageLayerD3D10::GetImageSRView(Image* aImage, bool& aHasAlpha, IDXGIKeyedMutex **aMutex)
michael@0 98 {
michael@0 99 NS_ASSERTION(aImage, "Null image.");
michael@0 100
michael@0 101 if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP) {
michael@0 102 RemoteBitmapImage *remoteImage =
michael@0 103 static_cast<RemoteBitmapImage*>(aImage);
michael@0 104
michael@0 105 if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
michael@0 106 nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData());
michael@0 107 dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize);
michael@0 108
michael@0 109 if (dat->mTexture) {
michael@0 110 device()->CreateShaderResourceView(dat->mTexture, nullptr, getter_AddRefs(dat->mSRView));
michael@0 111 aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, dat.forget());
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32;
michael@0 116 } else if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_DXGI_TEXTURE) {
michael@0 117 RemoteDXGITextureImage *remoteImage =
michael@0 118 static_cast<RemoteDXGITextureImage*>(aImage);
michael@0 119
michael@0 120 remoteImage->GetD3D10TextureBackendData(device());
michael@0 121
michael@0 122 aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32;
michael@0 123 } else if (aImage->GetFormat() == ImageFormat::CAIRO_SURFACE) {
michael@0 124 CairoImage *cairoImage =
michael@0 125 static_cast<CairoImage*>(aImage);
michael@0 126
michael@0 127 RefPtr<SourceSurface> surf = cairoImage->GetAsSourceSurface();
michael@0 128 if (!surf) {
michael@0 129 return nullptr;
michael@0 130 }
michael@0 131
michael@0 132 if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
michael@0 133 nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData());
michael@0 134 dat->mTexture = SurfaceToTexture(device(), surf, cairoImage->GetSize());
michael@0 135
michael@0 136 if (dat->mTexture) {
michael@0 137 device()->CreateShaderResourceView(dat->mTexture, nullptr, getter_AddRefs(dat->mSRView));
michael@0 138 aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, dat.forget());
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 aHasAlpha = surf->GetFormat() == SurfaceFormat::B8G8R8A8;
michael@0 143 } else if (aImage->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) {
michael@0 144 if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
michael@0 145 // Use resource sharing to open the D3D9 texture as a D3D10 texture,
michael@0 146 HRESULT hr;
michael@0 147 D3D9SurfaceImage* d3dImage = reinterpret_cast<D3D9SurfaceImage*>(aImage);
michael@0 148 nsRefPtr<ID3D10Texture2D> texture;
michael@0 149 hr = device()->OpenSharedResource(d3dImage->GetShareHandle(),
michael@0 150 IID_ID3D10Texture2D,
michael@0 151 (void**)getter_AddRefs(texture));
michael@0 152 NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
michael@0 153
michael@0 154 nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData());
michael@0 155 dat->mTexture = texture;
michael@0 156
michael@0 157 hr = device()->CreateShaderResourceView(dat->mTexture, nullptr, getter_AddRefs(dat->mSRView));
michael@0 158 NS_ENSURE_TRUE(SUCCEEDED(hr) && dat->mSRView, nullptr);
michael@0 159
michael@0 160 aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, dat.forget());
michael@0 161 }
michael@0 162 aHasAlpha = false;
michael@0 163 } else {
michael@0 164 NS_WARNING("Incorrect image type.");
michael@0 165 return nullptr;
michael@0 166 }
michael@0 167
michael@0 168 TextureD3D10BackendData *data =
michael@0 169 static_cast<TextureD3D10BackendData*>(aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10));
michael@0 170
michael@0 171 if (!data) {
michael@0 172 return nullptr;
michael@0 173 }
michael@0 174
michael@0 175 if (aMutex &&
michael@0 176 SUCCEEDED(data->mTexture->QueryInterface(IID_IDXGIKeyedMutex, (void**)aMutex))) {
michael@0 177 if (FAILED((*aMutex)->AcquireSync(0, 0))) {
michael@0 178 NS_WARNING("Failed to acquire sync on keyed mutex, plugin forgot to release?");
michael@0 179 return nullptr;
michael@0 180 }
michael@0 181 }
michael@0 182
michael@0 183 nsRefPtr<ID3D10Device> dev;
michael@0 184 data->mTexture->GetDevice(getter_AddRefs(dev));
michael@0 185 if (dev != device()) {
michael@0 186 return nullptr;
michael@0 187 }
michael@0 188
michael@0 189 return data->mSRView;
michael@0 190 }
michael@0 191
michael@0 192 void
michael@0 193 ImageLayerD3D10::RenderLayer()
michael@0 194 {
michael@0 195 ImageContainer *container = GetContainer();
michael@0 196 if (!container) {
michael@0 197 return;
michael@0 198 }
michael@0 199
michael@0 200 AutoLockImage autoLock(container);
michael@0 201
michael@0 202 Image *image = autoLock.GetImage();
michael@0 203 if (!image) {
michael@0 204 return;
michael@0 205 }
michael@0 206
michael@0 207 IntSize size = image->GetSize();
michael@0 208
michael@0 209 SetEffectTransformAndOpacity();
michael@0 210
michael@0 211 ID3D10EffectTechnique *technique;
michael@0 212 nsRefPtr<IDXGIKeyedMutex> keyedMutex;
michael@0 213
michael@0 214 if (image->GetFormat() == ImageFormat::CAIRO_SURFACE ||
michael@0 215 image->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP ||
michael@0 216 image->GetFormat() == ImageFormat::REMOTE_IMAGE_DXGI_TEXTURE ||
michael@0 217 image->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) {
michael@0 218 NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE ||
michael@0 219 !static_cast<CairoImage*>(image)->mSourceSurface ||
michael@0 220 static_cast<CairoImage*>(image)->mSourceSurface->GetFormat() != SurfaceFormat::A8,
michael@0 221 "Image layer has alpha image");
michael@0 222 bool hasAlpha = false;
michael@0 223
michael@0 224 nsRefPtr<ID3D10ShaderResourceView> srView = GetImageSRView(image, hasAlpha, getter_AddRefs(keyedMutex));
michael@0 225 if (!srView) {
michael@0 226 return;
michael@0 227 }
michael@0 228
michael@0 229 uint8_t shaderFlags = SHADER_PREMUL;
michael@0 230 shaderFlags |= LoadMaskTexture();
michael@0 231 shaderFlags |= hasAlpha
michael@0 232 ? SHADER_RGBA : SHADER_RGB;
michael@0 233 shaderFlags |= mFilter == GraphicsFilter::FILTER_NEAREST
michael@0 234 ? SHADER_POINT : SHADER_LINEAR;
michael@0 235 technique = SelectShader(shaderFlags);
michael@0 236
michael@0 237
michael@0 238 effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView);
michael@0 239
michael@0 240 effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
michael@0 241 ShaderConstantRectD3D10(
michael@0 242 (float)0,
michael@0 243 (float)0,
michael@0 244 (float)size.width,
michael@0 245 (float)size.height)
michael@0 246 );
michael@0 247 } else if (image->GetFormat() == ImageFormat::PLANAR_YCBCR) {
michael@0 248 PlanarYCbCrImage *yuvImage =
michael@0 249 static_cast<PlanarYCbCrImage*>(image);
michael@0 250
michael@0 251 if (!yuvImage->IsValid()) {
michael@0 252 return;
michael@0 253 }
michael@0 254
michael@0 255 if (!yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
michael@0 256 AllocateTexturesYCbCr(yuvImage);
michael@0 257 }
michael@0 258
michael@0 259 PlanarYCbCrD3D10BackendData *data =
michael@0 260 static_cast<PlanarYCbCrD3D10BackendData*>(yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10));
michael@0 261
michael@0 262 if (!data) {
michael@0 263 return;
michael@0 264 }
michael@0 265
michael@0 266 nsRefPtr<ID3D10Device> dev;
michael@0 267 data->mYTexture->GetDevice(getter_AddRefs(dev));
michael@0 268 if (dev != device()) {
michael@0 269 return;
michael@0 270 }
michael@0 271
michael@0 272 // TODO: At some point we should try to deal with mFilter here, you don't
michael@0 273 // really want to use point filtering in the case of NEAREST, since that
michael@0 274 // would also use point filtering for Chroma upsampling. Where most likely
michael@0 275 // the user would only want point filtering for final RGB image upsampling.
michael@0 276
michael@0 277 technique = SelectShader(SHADER_YCBCR | LoadMaskTexture());
michael@0 278
michael@0 279 effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(data->mYView);
michael@0 280 effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(data->mCbView);
michael@0 281 effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(data->mCrView);
michael@0 282
michael@0 283 /*
michael@0 284 * Send 3d control data and metadata to NV3DVUtils
michael@0 285 */
michael@0 286 if (GetNv3DVUtils()) {
michael@0 287 Nv_Stereo_Mode mode;
michael@0 288 switch (yuvImage->GetData()->mStereoMode) {
michael@0 289 case StereoMode::LEFT_RIGHT:
michael@0 290 mode = NV_STEREO_MODE_LEFT_RIGHT;
michael@0 291 break;
michael@0 292 case StereoMode::RIGHT_LEFT:
michael@0 293 mode = NV_STEREO_MODE_RIGHT_LEFT;
michael@0 294 break;
michael@0 295 case StereoMode::BOTTOM_TOP:
michael@0 296 mode = NV_STEREO_MODE_BOTTOM_TOP;
michael@0 297 break;
michael@0 298 case StereoMode::TOP_BOTTOM:
michael@0 299 mode = NV_STEREO_MODE_TOP_BOTTOM;
michael@0 300 break;
michael@0 301 case StereoMode::MONO:
michael@0 302 mode = NV_STEREO_MODE_MONO;
michael@0 303 break;
michael@0 304 }
michael@0 305
michael@0 306 // Send control data even in mono case so driver knows to leave stereo mode.
michael@0 307 GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
michael@0 308
michael@0 309 if (yuvImage->GetData()->mStereoMode != StereoMode::MONO) {
michael@0 310 // Dst resource is optional
michael@0 311 GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->GetData()->mYSize.width,
michael@0 312 (unsigned int)yuvImage->GetData()->mYSize.height, (HANDLE)(data->mYTexture), (HANDLE)(nullptr));
michael@0 313 }
michael@0 314 }
michael@0 315
michael@0 316 effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
michael@0 317 ShaderConstantRectD3D10(
michael@0 318 (float)0,
michael@0 319 (float)0,
michael@0 320 (float)size.width,
michael@0 321 (float)size.height)
michael@0 322 );
michael@0 323
michael@0 324 effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
michael@0 325 ShaderConstantRectD3D10(
michael@0 326 (float)yuvImage->GetData()->mPicX / yuvImage->GetData()->mYSize.width,
michael@0 327 (float)yuvImage->GetData()->mPicY / yuvImage->GetData()->mYSize.height,
michael@0 328 (float)yuvImage->GetData()->mPicSize.width / yuvImage->GetData()->mYSize.width,
michael@0 329 (float)yuvImage->GetData()->mPicSize.height / yuvImage->GetData()->mYSize.height)
michael@0 330 );
michael@0 331 }
michael@0 332
michael@0 333 bool resetTexCoords = image->GetFormat() == ImageFormat::PLANAR_YCBCR;
michael@0 334 image = nullptr;
michael@0 335 autoLock.Unlock();
michael@0 336
michael@0 337 technique->GetPassByIndex(0)->Apply(0);
michael@0 338 device()->Draw(4, 0);
michael@0 339
michael@0 340 if (keyedMutex) {
michael@0 341 keyedMutex->ReleaseSync(0);
michael@0 342 }
michael@0 343
michael@0 344 if (resetTexCoords) {
michael@0 345 effect()->GetVariableByName("vTextureCoords")->AsVector()->
michael@0 346 SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
michael@0 347 }
michael@0 348
michael@0 349 GetContainer()->NotifyPaintedImage(image);
michael@0 350 }
michael@0 351
michael@0 352 void ImageLayerD3D10::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
michael@0 353 {
michael@0 354 nsAutoPtr<PlanarYCbCrD3D10BackendData> backendData(
michael@0 355 new PlanarYCbCrD3D10BackendData);
michael@0 356
michael@0 357 const PlanarYCbCrData *data = aImage->GetData();
michael@0 358
michael@0 359 D3D10_SUBRESOURCE_DATA dataY;
michael@0 360 D3D10_SUBRESOURCE_DATA dataCb;
michael@0 361 D3D10_SUBRESOURCE_DATA dataCr;
michael@0 362 CD3D10_TEXTURE2D_DESC descY(DXGI_FORMAT_A8_UNORM,
michael@0 363 data->mYSize.width,
michael@0 364 data->mYSize.height, 1, 1);
michael@0 365 CD3D10_TEXTURE2D_DESC descCbCr(DXGI_FORMAT_A8_UNORM,
michael@0 366 data->mCbCrSize.width,
michael@0 367 data->mCbCrSize.height, 1, 1);
michael@0 368
michael@0 369 descY.Usage = descCbCr.Usage = D3D10_USAGE_IMMUTABLE;
michael@0 370
michael@0 371 dataY.pSysMem = data->mYChannel;
michael@0 372 dataY.SysMemPitch = data->mYStride;
michael@0 373 dataCb.pSysMem = data->mCbChannel;
michael@0 374 dataCb.SysMemPitch = data->mCbCrStride;
michael@0 375 dataCr.pSysMem = data->mCrChannel;
michael@0 376 dataCr.SysMemPitch = data->mCbCrStride;
michael@0 377
michael@0 378 HRESULT hr = device()->CreateTexture2D(&descY, &dataY, getter_AddRefs(backendData->mYTexture));
michael@0 379 if (!FAILED(hr)) {
michael@0 380 hr = device()->CreateTexture2D(&descCbCr, &dataCb, getter_AddRefs(backendData->mCbTexture));
michael@0 381 }
michael@0 382 if (!FAILED(hr)) {
michael@0 383 hr = device()->CreateTexture2D(&descCbCr, &dataCr, getter_AddRefs(backendData->mCrTexture));
michael@0 384 }
michael@0 385 if (FAILED(hr)) {
michael@0 386 LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("PlanarYCbCrImageD3D10::AllocateTextures(): Failed to create texture"),
michael@0 387 hr);
michael@0 388 return;
michael@0 389 }
michael@0 390 device()->CreateShaderResourceView(backendData->mYTexture, nullptr, getter_AddRefs(backendData->mYView));
michael@0 391 device()->CreateShaderResourceView(backendData->mCbTexture, nullptr, getter_AddRefs(backendData->mCbView));
michael@0 392 device()->CreateShaderResourceView(backendData->mCrTexture, nullptr, getter_AddRefs(backendData->mCrView));
michael@0 393
michael@0 394 aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, backendData.forget());
michael@0 395 }
michael@0 396
michael@0 397 already_AddRefed<ID3D10ShaderResourceView>
michael@0 398 ImageLayerD3D10::GetAsTexture(gfx::IntSize* aSize)
michael@0 399 {
michael@0 400 if (!GetContainer()) {
michael@0 401 return nullptr;
michael@0 402 }
michael@0 403
michael@0 404 AutoLockImage autoLock(GetContainer());
michael@0 405
michael@0 406 Image *image = autoLock.GetImage();
michael@0 407 if (!image) {
michael@0 408 return nullptr;
michael@0 409 }
michael@0 410
michael@0 411 if (image->GetFormat() != ImageFormat::CAIRO_SURFACE) {
michael@0 412 return nullptr;
michael@0 413 }
michael@0 414
michael@0 415 *aSize = image->GetSize();
michael@0 416 bool dontCare;
michael@0 417 nsRefPtr<ID3D10ShaderResourceView> result = GetImageSRView(image, dontCare);
michael@0 418 return result.forget();
michael@0 419 }
michael@0 420
michael@0 421 TemporaryRef<gfx::SourceSurface>
michael@0 422 RemoteDXGITextureImage::GetAsSourceSurface()
michael@0 423 {
michael@0 424 nsRefPtr<ID3D10Device1> device =
michael@0 425 gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
michael@0 426 if (!device) {
michael@0 427 NS_WARNING("Cannot readback from shared texture because no D3D10 device is available.");
michael@0 428 return nullptr;
michael@0 429 }
michael@0 430
michael@0 431 TextureD3D10BackendData* data = GetD3D10TextureBackendData(device);
michael@0 432
michael@0 433 if (!data) {
michael@0 434 return nullptr;
michael@0 435 }
michael@0 436
michael@0 437 nsRefPtr<IDXGIKeyedMutex> keyedMutex;
michael@0 438
michael@0 439 if (FAILED(data->mTexture->QueryInterface(IID_IDXGIKeyedMutex, getter_AddRefs(keyedMutex)))) {
michael@0 440 NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
michael@0 441 return nullptr;
michael@0 442 }
michael@0 443
michael@0 444 if (FAILED(keyedMutex->AcquireSync(0, 0))) {
michael@0 445 NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?");
michael@0 446 return nullptr;
michael@0 447 }
michael@0 448
michael@0 449 D3D10_TEXTURE2D_DESC desc;
michael@0 450
michael@0 451 data->mTexture->GetDesc(&desc);
michael@0 452
michael@0 453 desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
michael@0 454 desc.BindFlags = 0;
michael@0 455 desc.MiscFlags = 0;
michael@0 456 desc.Usage = D3D10_USAGE_STAGING;
michael@0 457
michael@0 458 nsRefPtr<ID3D10Texture2D> softTexture;
michael@0 459 HRESULT hr = device->CreateTexture2D(&desc, nullptr, getter_AddRefs(softTexture));
michael@0 460
michael@0 461 if (FAILED(hr)) {
michael@0 462 NS_WARNING("Failed to create 2D staging texture.");
michael@0 463 return nullptr;
michael@0 464 }
michael@0 465
michael@0 466 device->CopyResource(softTexture, data->mTexture);
michael@0 467 keyedMutex->ReleaseSync(0);
michael@0 468
michael@0 469 RefPtr<gfx::DataSourceSurface> surface
michael@0 470 = gfx::Factory::CreateDataSourceSurface(mSize,
michael@0 471 mFormat == RemoteImageData::BGRX32
michael@0 472 ? gfx::SurfaceFormat::B8G8R8X8
michael@0 473 : gfx::SurfaceFormat::B8G8R8A8);
michael@0 474
michael@0 475 if (!surface) {
michael@0 476 NS_WARNING("Failed to create SourceSurface for DXGI texture.");
michael@0 477 return nullptr;
michael@0 478 }
michael@0 479
michael@0 480 gfx::DataSourceSurface::MappedSurface mappedSurface;
michael@0 481 if (!surface->Map(gfx::DataSourceSurface::WRITE, &mappedSurface)) {
michael@0 482 NS_WARNING("Failed to map source surface");
michael@0 483 return nullptr;
michael@0 484 }
michael@0 485
michael@0 486 D3D10_MAPPED_TEXTURE2D mapped;
michael@0 487 softTexture->Map(0, D3D10_MAP_READ, 0, &mapped);
michael@0 488
michael@0 489 for (int y = 0; y < mSize.height; y++) {
michael@0 490 memcpy(mappedSurface.mData + mappedSurface.mStride * y,
michael@0 491 (unsigned char*)(mapped.pData) + mapped.RowPitch * y,
michael@0 492 mSize.width * 4);
michael@0 493 }
michael@0 494
michael@0 495 softTexture->Unmap(0);
michael@0 496 surface->Unmap();
michael@0 497
michael@0 498 return surface;
michael@0 499 }
michael@0 500
michael@0 501 TextureD3D10BackendData*
michael@0 502 RemoteDXGITextureImage::GetD3D10TextureBackendData(ID3D10Device *aDevice)
michael@0 503 {
michael@0 504 if (GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10)) {
michael@0 505 TextureD3D10BackendData *data =
michael@0 506 static_cast<TextureD3D10BackendData*>(GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10));
michael@0 507
michael@0 508 nsRefPtr<ID3D10Device> device;
michael@0 509 data->mTexture->GetDevice(getter_AddRefs(device));
michael@0 510
michael@0 511 if (device == aDevice) {
michael@0 512 return data;
michael@0 513 }
michael@0 514 }
michael@0 515 nsRefPtr<ID3D10Texture2D> texture;
michael@0 516 aDevice->OpenSharedResource(mHandle, __uuidof(ID3D10Texture2D), getter_AddRefs(texture));
michael@0 517
michael@0 518 if (!texture) {
michael@0 519 NS_WARNING("Failed to get texture for shared texture handle.");
michael@0 520 return nullptr;
michael@0 521 }
michael@0 522
michael@0 523 nsAutoPtr<TextureD3D10BackendData> data(new TextureD3D10BackendData());
michael@0 524
michael@0 525 data->mTexture = texture;
michael@0 526
michael@0 527 aDevice->CreateShaderResourceView(texture, nullptr, getter_AddRefs(data->mSRView));
michael@0 528
michael@0 529 SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D10, data);
michael@0 530
michael@0 531 return data.forget();
michael@0 532 }
michael@0 533
michael@0 534 } /* layers */
michael@0 535 } /* mozilla */

mercurial