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