1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,576 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/gfx/2D.h" 1.10 +#include "mozilla/gfx/Point.h" 1.11 +#include "mozilla/RefPtr.h" 1.12 +#include "mozilla/layers/PLayerTransaction.h" 1.13 +#include "gfxSharedImageSurface.h" 1.14 + 1.15 +#include "ImageLayerD3D9.h" 1.16 +#include "ThebesLayerD3D9.h" 1.17 +#include "gfxPlatform.h" 1.18 +#include "gfx2DGlue.h" 1.19 +#include "yuv_convert.h" 1.20 +#include "nsIServiceManager.h" 1.21 +#include "nsIConsoleService.h" 1.22 +#include "Nv3DVUtils.h" 1.23 +#include "D3D9SurfaceImage.h" 1.24 + 1.25 +namespace mozilla { 1.26 +namespace layers { 1.27 + 1.28 +using namespace mozilla::gfx; 1.29 + 1.30 +static inline _D3DFORMAT 1.31 +D3dFormatForSurfaceFormat(SurfaceFormat aFormat) 1.32 +{ 1.33 + if (aFormat == SurfaceFormat::A8) { 1.34 + return D3DFMT_A8; 1.35 + } 1.36 + 1.37 + return D3DFMT_A8R8G8B8; 1.38 +} 1.39 + 1.40 +static already_AddRefed<IDirect3DTexture9> 1.41 +DataToTexture(IDirect3DDevice9 *aDevice, 1.42 + unsigned char *aData, 1.43 + int aStride, 1.44 + const IntSize &aSize, 1.45 + _D3DFORMAT aFormat) 1.46 +{ 1.47 + nsRefPtr<IDirect3DTexture9> texture; 1.48 + nsRefPtr<IDirect3DDevice9Ex> deviceEx; 1.49 + aDevice->QueryInterface(IID_IDirect3DDevice9Ex, 1.50 + (void**)getter_AddRefs(deviceEx)); 1.51 + 1.52 + nsRefPtr<IDirect3DSurface9> surface; 1.53 + D3DLOCKED_RECT lockedRect; 1.54 + if (deviceEx) { 1.55 + // D3D9Ex doesn't support managed textures. We could use dynamic textures 1.56 + // here but since Images are immutable that probably isn't such a great 1.57 + // idea. 1.58 + if (FAILED(aDevice-> 1.59 + CreateTexture(aSize.width, aSize.height, 1.60 + 1, 0, aFormat, D3DPOOL_DEFAULT, 1.61 + getter_AddRefs(texture), nullptr))) 1.62 + { 1.63 + return nullptr; 1.64 + } 1.65 + 1.66 + nsRefPtr<IDirect3DTexture9> tmpTexture; 1.67 + if (FAILED(aDevice-> 1.68 + CreateTexture(aSize.width, aSize.height, 1.69 + 1, 0, aFormat, D3DPOOL_SYSTEMMEM, 1.70 + getter_AddRefs(tmpTexture), nullptr))) 1.71 + { 1.72 + return nullptr; 1.73 + } 1.74 + 1.75 + tmpTexture->GetSurfaceLevel(0, getter_AddRefs(surface)); 1.76 + surface->LockRect(&lockedRect, nullptr, 0); 1.77 + NS_ASSERTION(lockedRect.pBits, "Could not lock surface"); 1.78 + } else { 1.79 + if (FAILED(aDevice-> 1.80 + CreateTexture(aSize.width, aSize.height, 1.81 + 1, 0, aFormat, D3DPOOL_MANAGED, 1.82 + getter_AddRefs(texture), nullptr))) 1.83 + { 1.84 + return nullptr; 1.85 + } 1.86 + 1.87 + /* lock the entire texture */ 1.88 + texture->LockRect(0, &lockedRect, nullptr, 0); 1.89 + } 1.90 + 1.91 + uint32_t width = aSize.width; 1.92 + if (aFormat == D3DFMT_A8R8G8B8) { 1.93 + width *= 4; 1.94 + } 1.95 + for (int y = 0; y < aSize.height; y++) { 1.96 + memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y, 1.97 + aData + aStride * y, 1.98 + width); 1.99 + } 1.100 + 1.101 + if (deviceEx) { 1.102 + surface->UnlockRect(); 1.103 + nsRefPtr<IDirect3DSurface9> dstSurface; 1.104 + texture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); 1.105 + aDevice->UpdateSurface(surface, nullptr, dstSurface, nullptr); 1.106 + } else { 1.107 + texture->UnlockRect(0); 1.108 + } 1.109 + 1.110 + return texture.forget(); 1.111 +} 1.112 + 1.113 +static already_AddRefed<IDirect3DTexture9> 1.114 +OpenSharedTexture(const D3DSURFACE_DESC& aDesc, 1.115 + HANDLE aShareHandle, 1.116 + IDirect3DDevice9 *aDevice) 1.117 +{ 1.118 + MOZ_ASSERT(aDesc.Format == D3DFMT_X8R8G8B8); 1.119 + 1.120 + // Open the frame from DXVA's device in our device using the resource 1.121 + // sharing handle. 1.122 + nsRefPtr<IDirect3DTexture9> sharedTexture; 1.123 + HRESULT hr = aDevice->CreateTexture(aDesc.Width, 1.124 + aDesc.Height, 1.125 + 1, 1.126 + D3DUSAGE_RENDERTARGET, 1.127 + D3DFMT_X8R8G8B8, 1.128 + D3DPOOL_DEFAULT, 1.129 + getter_AddRefs(sharedTexture), 1.130 + &aShareHandle); 1.131 + if (FAILED(hr)) { 1.132 + NS_WARNING("Failed to open shared texture on our device"); 1.133 + } 1.134 + return sharedTexture.forget(); 1.135 +} 1.136 + 1.137 +static already_AddRefed<IDirect3DTexture9> 1.138 +SurfaceToTexture(IDirect3DDevice9 *aDevice, 1.139 + SourceSurface *aSurface, 1.140 + const IntSize &aSize) 1.141 +{ 1.142 + RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface(); 1.143 + if (!dataSurface) { 1.144 + return nullptr; 1.145 + } 1.146 + DataSourceSurface::MappedSurface map; 1.147 + if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) { 1.148 + return nullptr; 1.149 + } 1.150 + nsRefPtr<IDirect3DTexture9> texture = 1.151 + DataToTexture(aDevice, map.mData, map.mStride, aSize, 1.152 + D3dFormatForSurfaceFormat(dataSurface->GetFormat())); 1.153 + dataSurface->Unmap(); 1.154 + return texture.forget(); 1.155 +} 1.156 + 1.157 +static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage, 1.158 + IDirect3DDevice9 *aDevice, 1.159 + LayerManagerD3D9 *aManager) 1.160 +{ 1.161 + nsAutoPtr<PlanarYCbCrD3D9BackendData> backendData( 1.162 + new PlanarYCbCrD3D9BackendData); 1.163 + 1.164 + const PlanarYCbCrData *data = aImage->GetData(); 1.165 + 1.166 + D3DLOCKED_RECT lockrectY; 1.167 + D3DLOCKED_RECT lockrectCb; 1.168 + D3DLOCKED_RECT lockrectCr; 1.169 + uint8_t* src; 1.170 + uint8_t* dest; 1.171 + 1.172 + nsRefPtr<IDirect3DSurface9> tmpSurfaceY; 1.173 + nsRefPtr<IDirect3DSurface9> tmpSurfaceCb; 1.174 + nsRefPtr<IDirect3DSurface9> tmpSurfaceCr; 1.175 + 1.176 + nsRefPtr<IDirect3DDevice9Ex> deviceEx; 1.177 + aDevice->QueryInterface(IID_IDirect3DDevice9Ex, 1.178 + getter_AddRefs(deviceEx)); 1.179 + 1.180 + bool isD3D9Ex = deviceEx; 1.181 + 1.182 + if (isD3D9Ex) { 1.183 + nsRefPtr<IDirect3DTexture9> tmpYTexture; 1.184 + nsRefPtr<IDirect3DTexture9> tmpCbTexture; 1.185 + nsRefPtr<IDirect3DTexture9> tmpCrTexture; 1.186 + // D3D9Ex does not support the managed pool, could use dynamic textures 1.187 + // here. But since an Image is immutable static textures are probably a 1.188 + // better idea. 1.189 + 1.190 + HRESULT hr; 1.191 + hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height, 1.192 + 1, 0, D3DFMT_A8, D3DPOOL_DEFAULT, 1.193 + getter_AddRefs(backendData->mYTexture), nullptr); 1.194 + if (!FAILED(hr)) { 1.195 + hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.196 + 1, 0, D3DFMT_A8, D3DPOOL_DEFAULT, 1.197 + getter_AddRefs(backendData->mCbTexture), nullptr); 1.198 + } 1.199 + if (!FAILED(hr)) { 1.200 + hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.201 + 1, 0, D3DFMT_A8, D3DPOOL_DEFAULT, 1.202 + getter_AddRefs(backendData->mCrTexture), nullptr); 1.203 + } 1.204 + if (!FAILED(hr)) { 1.205 + hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height, 1.206 + 1, 0, D3DFMT_A8, D3DPOOL_SYSTEMMEM, 1.207 + getter_AddRefs(tmpYTexture), nullptr); 1.208 + } 1.209 + if (!FAILED(hr)) { 1.210 + hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.211 + 1, 0, D3DFMT_A8, D3DPOOL_SYSTEMMEM, 1.212 + getter_AddRefs(tmpCbTexture), nullptr); 1.213 + } 1.214 + if (!FAILED(hr)) { 1.215 + hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.216 + 1, 0, D3DFMT_A8, D3DPOOL_SYSTEMMEM, 1.217 + getter_AddRefs(tmpCrTexture), nullptr); 1.218 + } 1.219 + 1.220 + if (FAILED(hr)) { 1.221 + aManager->ReportFailure(NS_LITERAL_CSTRING("PlanarYCbCrImageD3D9::AllocateTextures(): Failed to create texture (isD3D9Ex)"), 1.222 + hr); 1.223 + return; 1.224 + } 1.225 + 1.226 + tmpYTexture->GetSurfaceLevel(0, getter_AddRefs(tmpSurfaceY)); 1.227 + tmpCbTexture->GetSurfaceLevel(0, getter_AddRefs(tmpSurfaceCb)); 1.228 + tmpCrTexture->GetSurfaceLevel(0, getter_AddRefs(tmpSurfaceCr)); 1.229 + tmpSurfaceY->LockRect(&lockrectY, nullptr, 0); 1.230 + tmpSurfaceCb->LockRect(&lockrectCb, nullptr, 0); 1.231 + tmpSurfaceCr->LockRect(&lockrectCr, nullptr, 0); 1.232 + } else { 1.233 + HRESULT hr; 1.234 + hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height, 1.235 + 1, 0, D3DFMT_A8, D3DPOOL_MANAGED, 1.236 + getter_AddRefs(backendData->mYTexture), nullptr); 1.237 + if (!FAILED(hr)) { 1.238 + aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.239 + 1, 0, D3DFMT_A8, D3DPOOL_MANAGED, 1.240 + getter_AddRefs(backendData->mCbTexture), nullptr); 1.241 + } 1.242 + if (!FAILED(hr)) { 1.243 + aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height, 1.244 + 1, 0, D3DFMT_A8, D3DPOOL_MANAGED, 1.245 + getter_AddRefs(backendData->mCrTexture), nullptr); 1.246 + } 1.247 + 1.248 + if (FAILED(hr)) { 1.249 + aManager->ReportFailure(NS_LITERAL_CSTRING("PlanarYCbCrImageD3D9::AllocateTextures(): Failed to create texture (!isD3D9Ex)"), 1.250 + hr); 1.251 + return; 1.252 + } 1.253 + 1.254 + /* lock the entire texture */ 1.255 + backendData->mYTexture->LockRect(0, &lockrectY, nullptr, 0); 1.256 + backendData->mCbTexture->LockRect(0, &lockrectCb, nullptr, 0); 1.257 + backendData->mCrTexture->LockRect(0, &lockrectCr, nullptr, 0); 1.258 + } 1.259 + 1.260 + src = data->mYChannel; 1.261 + //FIX cast 1.262 + dest = (uint8_t*)lockrectY.pBits; 1.263 + 1.264 + // copy over data 1.265 + for (int h=0; h<data->mYSize.height; h++) { 1.266 + memcpy(dest, src, data->mYSize.width); 1.267 + dest += lockrectY.Pitch; 1.268 + src += data->mYStride; 1.269 + } 1.270 + 1.271 + src = data->mCbChannel; 1.272 + //FIX cast 1.273 + dest = (uint8_t*)lockrectCb.pBits; 1.274 + 1.275 + // copy over data 1.276 + for (int h=0; h<data->mCbCrSize.height; h++) { 1.277 + memcpy(dest, src, data->mCbCrSize.width); 1.278 + dest += lockrectCb.Pitch; 1.279 + src += data->mCbCrStride; 1.280 + } 1.281 + 1.282 + src = data->mCrChannel; 1.283 + //FIX cast 1.284 + dest = (uint8_t*)lockrectCr.pBits; 1.285 + 1.286 + // copy over data 1.287 + for (int h=0; h<data->mCbCrSize.height; h++) { 1.288 + memcpy(dest, src, data->mCbCrSize.width); 1.289 + dest += lockrectCr.Pitch; 1.290 + src += data->mCbCrStride; 1.291 + } 1.292 + 1.293 + if (isD3D9Ex) { 1.294 + tmpSurfaceY->UnlockRect(); 1.295 + tmpSurfaceCb->UnlockRect(); 1.296 + tmpSurfaceCr->UnlockRect(); 1.297 + nsRefPtr<IDirect3DSurface9> dstSurface; 1.298 + backendData->mYTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); 1.299 + aDevice->UpdateSurface(tmpSurfaceY, nullptr, dstSurface, nullptr); 1.300 + backendData->mCbTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); 1.301 + aDevice->UpdateSurface(tmpSurfaceCb, nullptr, dstSurface, nullptr); 1.302 + backendData->mCrTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); 1.303 + aDevice->UpdateSurface(tmpSurfaceCr, nullptr, dstSurface, nullptr); 1.304 + } else { 1.305 + backendData->mYTexture->UnlockRect(0); 1.306 + backendData->mCbTexture->UnlockRect(0); 1.307 + backendData->mCrTexture->UnlockRect(0); 1.308 + } 1.309 + 1.310 + aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9, backendData.forget()); 1.311 +} 1.312 + 1.313 +Layer* 1.314 +ImageLayerD3D9::GetLayer() 1.315 +{ 1.316 + return this; 1.317 +} 1.318 + 1.319 +/* 1.320 + * Returns a texture which backs aImage 1.321 + * Will only work if aImage is a cairo or remote image. 1.322 + * Returns nullptr if unsuccessful. 1.323 + * If successful, aHasAlpha will be set to true if the texture has an 1.324 + * alpha component, false otherwise. 1.325 + */ 1.326 +IDirect3DTexture9* 1.327 +ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha) 1.328 +{ 1.329 + NS_ASSERTION(aImage, "Null image."); 1.330 + 1.331 + if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP) { 1.332 + RemoteBitmapImage *remoteImage = 1.333 + static_cast<RemoteBitmapImage*>(aImage); 1.334 + 1.335 + if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)) { 1.336 + nsAutoPtr<TextureD3D9BackendData> dat(new TextureD3D9BackendData()); 1.337 + dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize, D3DFMT_A8R8G8B8); 1.338 + if (dat->mTexture) { 1.339 + aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9, dat.forget()); 1.340 + } 1.341 + } 1.342 + 1.343 + aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; 1.344 + } else if (aImage->GetFormat() == ImageFormat::CAIRO_SURFACE) { 1.345 + CairoImage *cairoImage = 1.346 + static_cast<CairoImage*>(aImage); 1.347 + 1.348 + RefPtr<SourceSurface> surf = cairoImage->GetAsSourceSurface(); 1.349 + if (!surf) { 1.350 + return nullptr; 1.351 + } 1.352 + 1.353 + if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)) { 1.354 + nsAutoPtr<TextureD3D9BackendData> dat(new TextureD3D9BackendData()); 1.355 + dat->mTexture = SurfaceToTexture(device(), surf, cairoImage->GetSize()); 1.356 + if (dat->mTexture) { 1.357 + aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9, dat.forget()); 1.358 + } 1.359 + } 1.360 + 1.361 + aHasAlpha = surf->GetFormat() == SurfaceFormat::B8G8R8A8; 1.362 + } else if (aImage->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) { 1.363 + if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)) { 1.364 + // The texture in which the frame is stored belongs to DXVA's D3D9 device. 1.365 + // We need to open it on our device before we can use it. 1.366 + nsAutoPtr<TextureD3D9BackendData> backendData(new TextureD3D9BackendData()); 1.367 + D3D9SurfaceImage* image = static_cast<D3D9SurfaceImage*>(aImage); 1.368 + backendData->mTexture = OpenSharedTexture(image->GetDesc(), image->GetShareHandle(), device()); 1.369 + if (backendData->mTexture) { 1.370 + aImage->SetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9, backendData.forget()); 1.371 + } 1.372 + } 1.373 + aHasAlpha = false; 1.374 + } else { 1.375 + NS_WARNING("Inappropriate image type."); 1.376 + return nullptr; 1.377 + } 1.378 + 1.379 + TextureD3D9BackendData *data = 1.380 + static_cast<TextureD3D9BackendData*>(aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)); 1.381 + 1.382 + if (!data) { 1.383 + return nullptr; 1.384 + } 1.385 + 1.386 + nsRefPtr<IDirect3DDevice9> dev; 1.387 + data->mTexture->GetDevice(getter_AddRefs(dev)); 1.388 + if (dev != device()) { 1.389 + return nullptr; 1.390 + } 1.391 + 1.392 + return data->mTexture; 1.393 +} 1.394 + 1.395 +void 1.396 +ImageLayerD3D9::RenderLayer() 1.397 +{ 1.398 + ImageContainer *container = GetContainer(); 1.399 + if (!container || mD3DManager->CompositingDisabled()) { 1.400 + return; 1.401 + } 1.402 + 1.403 + AutoLockImage autoLock(container); 1.404 + 1.405 + Image *image = autoLock.GetImage(); 1.406 + if (!image) { 1.407 + return; 1.408 + } 1.409 + 1.410 + SetShaderTransformAndOpacity(); 1.411 + 1.412 + gfx::IntSize size = image->GetSize(); 1.413 + 1.414 + if (image->GetFormat() == ImageFormat::CAIRO_SURFACE || 1.415 + image->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP || 1.416 + image->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) 1.417 + { 1.418 + NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE || 1.419 + !static_cast<CairoImage*>(image)->mSourceSurface || 1.420 + static_cast<CairoImage*>(image)->mSourceSurface->GetFormat() != SurfaceFormat::A8, 1.421 + "Image layer has alpha image"); 1.422 + 1.423 + bool hasAlpha = false; 1.424 + nsRefPtr<IDirect3DTexture9> texture = GetTexture(image, hasAlpha); 1.425 + 1.426 + device()->SetVertexShaderConstantF(CBvLayerQuad, 1.427 + ShaderConstantRect(0, 1.428 + 0, 1.429 + size.width, 1.430 + size.height), 1.431 + 1); 1.432 + 1.433 + if (hasAlpha) { 1.434 + mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, GetMaskLayer()); 1.435 + } else { 1.436 + mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER, GetMaskLayer()); 1.437 + } 1.438 + 1.439 + if (mFilter == GraphicsFilter::FILTER_NEAREST) { 1.440 + device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 1.441 + device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); 1.442 + } 1.443 + device()->SetTexture(0, texture); 1.444 + 1.445 + image = nullptr; 1.446 + autoLock.Unlock(); 1.447 + 1.448 + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 1.449 + if (mFilter == GraphicsFilter::FILTER_NEAREST) { 1.450 + device()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 1.451 + device()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 1.452 + } 1.453 + } else { 1.454 + PlanarYCbCrImage *yuvImage = 1.455 + static_cast<PlanarYCbCrImage*>(image); 1.456 + 1.457 + if (!yuvImage->IsValid()) { 1.458 + return; 1.459 + } 1.460 + 1.461 + if (!yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)) { 1.462 + AllocateTexturesYCbCr(yuvImage, device(), mD3DManager); 1.463 + } 1.464 + 1.465 + PlanarYCbCrD3D9BackendData *data = 1.466 + static_cast<PlanarYCbCrD3D9BackendData*>(yuvImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)); 1.467 + 1.468 + if (!data) { 1.469 + return; 1.470 + } 1.471 + 1.472 + nsRefPtr<IDirect3DDevice9> dev; 1.473 + data->mYTexture->GetDevice(getter_AddRefs(dev)); 1.474 + if (dev != device()) { 1.475 + return; 1.476 + } 1.477 + 1.478 + device()->SetVertexShaderConstantF(CBvLayerQuad, 1.479 + ShaderConstantRect(0, 1.480 + 0, 1.481 + size.width, 1.482 + size.height), 1.483 + 1); 1.484 + 1.485 + device()->SetVertexShaderConstantF(CBvTextureCoords, 1.486 + ShaderConstantRect( 1.487 + (float)yuvImage->GetData()->mPicX / yuvImage->GetData()->mYSize.width, 1.488 + (float)yuvImage->GetData()->mPicY / yuvImage->GetData()->mYSize.height, 1.489 + (float)yuvImage->GetData()->mPicSize.width / yuvImage->GetData()->mYSize.width, 1.490 + (float)yuvImage->GetData()->mPicSize.height / yuvImage->GetData()->mYSize.height 1.491 + ), 1.492 + 1); 1.493 + 1.494 + mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER, GetMaskLayer()); 1.495 + 1.496 + /* 1.497 + * Send 3d control data and metadata 1.498 + */ 1.499 + if (mD3DManager->GetNv3DVUtils()) { 1.500 + Nv_Stereo_Mode mode; 1.501 + switch (yuvImage->GetData()->mStereoMode) { 1.502 + case StereoMode::LEFT_RIGHT: 1.503 + mode = NV_STEREO_MODE_LEFT_RIGHT; 1.504 + break; 1.505 + case StereoMode::RIGHT_LEFT: 1.506 + mode = NV_STEREO_MODE_RIGHT_LEFT; 1.507 + break; 1.508 + case StereoMode::BOTTOM_TOP: 1.509 + mode = NV_STEREO_MODE_BOTTOM_TOP; 1.510 + break; 1.511 + case StereoMode::TOP_BOTTOM: 1.512 + mode = NV_STEREO_MODE_TOP_BOTTOM; 1.513 + break; 1.514 + case StereoMode::MONO: 1.515 + mode = NV_STEREO_MODE_MONO; 1.516 + break; 1.517 + } 1.518 + 1.519 + // Send control data even in mono case so driver knows to leave stereo mode. 1.520 + mD3DManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE); 1.521 + 1.522 + if (yuvImage->GetData()->mStereoMode != StereoMode::MONO) { 1.523 + mD3DManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE); 1.524 + 1.525 + nsRefPtr<IDirect3DSurface9> renderTarget; 1.526 + device()->GetRenderTarget(0, getter_AddRefs(renderTarget)); 1.527 + mD3DManager->GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->GetSize().width, 1.528 + (unsigned int)yuvImage->GetSize().height, (HANDLE)(data->mYTexture), (HANDLE)(renderTarget)); 1.529 + } 1.530 + } 1.531 + 1.532 + // Linear scaling is default here, adhering to mFilter is difficult since 1.533 + // presumably even with point filtering we'll still want chroma upsampling 1.534 + // to be linear. In the current approach we can't. 1.535 + device()->SetTexture(0, data->mYTexture); 1.536 + device()->SetTexture(1, data->mCbTexture); 1.537 + device()->SetTexture(2, data->mCrTexture); 1.538 + 1.539 + image = nullptr; 1.540 + data = nullptr; 1.541 + autoLock.Unlock(); 1.542 + 1.543 + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); 1.544 + 1.545 + device()->SetVertexShaderConstantF(CBvTextureCoords, 1.546 + ShaderConstantRect(0, 0, 1.0f, 1.0f), 1); 1.547 + } 1.548 + 1.549 + GetContainer()->NotifyPaintedImage(image); 1.550 +} 1.551 + 1.552 +already_AddRefed<IDirect3DTexture9> 1.553 +ImageLayerD3D9::GetAsTexture(gfx::IntSize* aSize) 1.554 +{ 1.555 + if (!GetContainer()) { 1.556 + return nullptr; 1.557 + } 1.558 + 1.559 + AutoLockImage autoLock(GetContainer()); 1.560 + 1.561 + Image *image = autoLock.GetImage(); 1.562 + 1.563 + if (!image) { 1.564 + return nullptr; 1.565 + } 1.566 + 1.567 + if (image->GetFormat() != ImageFormat::CAIRO_SURFACE && 1.568 + image->GetFormat() != ImageFormat::REMOTE_IMAGE_BITMAP) { 1.569 + return nullptr; 1.570 + } 1.571 + 1.572 + bool dontCare; 1.573 + *aSize = image->GetSize(); 1.574 + nsRefPtr<IDirect3DTexture9> result = GetTexture(image, dontCare); 1.575 + return result.forget(); 1.576 +} 1.577 + 1.578 +} /* layers */ 1.579 +} /* mozilla */