Sprite_T *CreateBasicSprite(const char *filename, Vec2i frame_size) { int x, y; int frames_per_row; Rect r; Sprite_T *s = NewSprite(); SDL_Surface *surf; if((surf = IMG_Load(filename)) == NULL) { printf("CreateBasicSprite(): %s failed to load!", filename); return NULL; } //SDL_InvertSurface(surf); r.w = (GLfloat)frame_size.x / (GLfloat)surf->w; r.h = (GLfloat)frame_size.y / (GLfloat)surf->h; s->numFrames = 0; frames_per_row = surf->w / frame_size.x; for(y = 0;y < surf->h / frame_size.y;y++) for(x = 0;x < surf->w / frame_size.x;x++) { r.x = x * r.w; r.y = 1.0f - (y+1) * r.h; s->frames[x+y*frames_per_row] = r; s->numFrames++; } s->numAnimations = 0; s->texId = SurfaceToTexture(surf); return s; }
/** * Returns a shader resource view for a Cairo or remote image. * Returns nsnull if unsuccessful. * If successful, aHasAlpha will be true iff the resulting texture * has an alpha component. */ ID3D10ShaderResourceView* ImageLayerD3D10::GetImageSRView(Image* aImage, bool& aHasAlpha) { NS_ASSERTION(aImage, "Null image."); if (aImage->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { RemoteBitmapImage *remoteImage = static_cast<RemoteBitmapImage*>(aImage); if (!aImage->GetBackendData(LayerManager::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat = new TextureD3D10BackendData(); dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); aImage->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); } } aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; } else if (aImage->GetFormat() == Image::CAIRO_SURFACE) { CairoImage *cairoImage = static_cast<CairoImage*>(aImage); if (!cairoImage->mSurface) { return nsnull; } if (!aImage->GetBackendData(LayerManager::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat = new TextureD3D10BackendData(); dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); aImage->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); } } aHasAlpha = cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; } else { NS_WARNING("Incorrect image type."); return nsnull; } TextureD3D10BackendData *data = static_cast<TextureD3D10BackendData*>(aImage->GetBackendData(LayerManager::LAYERS_D3D10)); if (!data) { return nsnull; } nsRefPtr<ID3D10Device> dev; data->mTexture->GetDevice(getter_AddRefs(dev)); if (dev != device()) { return nsnull; } return data->mSRView; }
/** * Convert text string into OpenGL texture. Returns its handle. */ GLuint TextToTextureColour(TTF_Font* Font, char* Text, SDL_Color Colour) { SDL_Surface* Initial; GLuint Texture; Initial = TTF_RenderText_Blended(Font, Text, Colour); Texture = SurfaceToTexture(Initial); SDL_FreeSurface(Initial); return Texture; }
void Sprite::LoadFrom(const std::string& path) { SDL_Surface* loadedSurface = IMG_Load(path.c_str()); if(loadedSurface != nullptr) { m_sdl_texture = SurfaceToTexture(loadedSurface); } else { log_error() << "Could not load surface from path." << IMG_GetError(); } // Display error log if image wasn't loaded. if(m_sdl_texture == nullptr) { log_error() << "Sprite load failed: " << path; } }
void CairoImageD3D10::SetData(const CairoImage::Data &aData) { mSize = aData.mSize; NS_ASSERTION(aData.mSurface->GetContentType() != gfxASurface::CONTENT_ALPHA, "Invalid content type passed to CairoImageD3D10."); mTexture = SurfaceToTexture(mDevice, aData.mSurface, mSize); if (!mTexture) { NS_WARNING("Failed to create texture for CairoImage."); return; } if (aData.mSurface->GetContentType() == gfxASurface::CONTENT_COLOR) { mHasAlpha = false; } else { mHasAlpha = true; } mDevice->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView)); }
/** * Returns a shader resource view for a Cairo or remote image. * Returns nullptr if unsuccessful. * If successful, aHasAlpha will be true iff the resulting texture * has an alpha component. */ ID3D10ShaderResourceView* ImageLayerD3D10::GetImageSRView(Image* aImage, bool& aHasAlpha, IDXGIKeyedMutex **aMutex) { NS_ASSERTION(aImage, "Null image."); if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP) { RemoteBitmapImage *remoteImage = static_cast<RemoteBitmapImage*>(aImage); if (!aImage->GetBackendData(mozilla::layers::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData()); dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); aImage->SetBackendData(mozilla::layers::LAYERS_D3D10, dat.forget()); } } aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; } else if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_DXGI_TEXTURE) { RemoteDXGITextureImage *remoteImage = static_cast<RemoteDXGITextureImage*>(aImage); remoteImage->GetD3D10TextureBackendData(device()); aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; } else if (aImage->GetFormat() == ImageFormat::CAIRO_SURFACE) { CairoImage *cairoImage = static_cast<CairoImage*>(aImage); if (!cairoImage->mSurface) { return nullptr; } if (!aImage->GetBackendData(mozilla::layers::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData()); dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); aImage->SetBackendData(mozilla::layers::LAYERS_D3D10, dat.forget()); } } aHasAlpha = cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; } else if (aImage->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) { if (!aImage->GetBackendData(mozilla::layers::LAYERS_D3D10)) { // Use resource sharing to open the D3D9 texture as a D3D10 texture, HRESULT hr; D3D9SurfaceImage* d3dImage = reinterpret_cast<D3D9SurfaceImage*>(aImage); nsRefPtr<ID3D10Texture2D> texture; hr = device()->OpenSharedResource(d3dImage->GetShareHandle(), IID_ID3D10Texture2D, (void**)getter_AddRefs(texture)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); nsAutoPtr<TextureD3D10BackendData> dat(new TextureD3D10BackendData()); dat->mTexture = texture; hr = device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); NS_ENSURE_TRUE(SUCCEEDED(hr) && dat->mSRView, nullptr); aImage->SetBackendData(mozilla::layers::LAYERS_D3D10, dat.forget()); } aHasAlpha = false; } else { NS_WARNING("Incorrect image type."); return nullptr; } TextureD3D10BackendData *data = static_cast<TextureD3D10BackendData*>(aImage->GetBackendData(mozilla::layers::LAYERS_D3D10)); if (!data) { return nullptr; } if (aMutex && SUCCEEDED(data->mTexture->QueryInterface(IID_IDXGIKeyedMutex, (void**)aMutex))) { if (FAILED((*aMutex)->AcquireSync(0, 0))) { NS_WARNING("Failed to acquire sync on keyed mutex, plugin forgot to release?"); return nullptr; } } nsRefPtr<ID3D10Device> dev; data->mTexture->GetDevice(getter_AddRefs(dev)); if (dev != device()) { return nullptr; } return data->mSRView; }
void ImageLayerD3D10::RenderLayer() { if (!GetContainer()) { return; } nsRefPtr<Image> image = GetContainer()->GetCurrentImage(); if (!image) { return; } SetEffectTransformAndOpacity(); ID3D10EffectTechnique *technique; if (GetContainer()->GetBackendType() != LayerManager::LAYERS_D3D10 || image->GetFormat() == Image::CAIRO_SURFACE) { gfxIntSize size; bool hasAlpha; nsRefPtr<ID3D10ShaderResourceView> srView; if (GetContainer()->GetBackendType() != LayerManager::LAYERS_D3D10) { nsRefPtr<gfxASurface> surf = GetContainer()->GetCurrentAsSurface(&size); nsRefPtr<ID3D10Texture2D> texture = SurfaceToTexture(device(), surf, size); if (!texture) { NS_WARNING("Failed to create texture for surface."); return; } hasAlpha = surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; device()->CreateShaderResourceView(texture, NULL, getter_AddRefs(srView)); } else { ImageContainerD3D10 *container = static_cast<ImageContainerD3D10*>(GetContainer()); if (container->device() != device()) { container->SetDevice(device()); } // image->GetFormat() == Image::CAIRO_SURFACE CairoImageD3D10 *cairoImage = static_cast<CairoImageD3D10*>(image.get()); if (cairoImage->mDevice != device()) { // This shader resource view was for an old device! Can't draw that // now. return; } srView = cairoImage->mSRView; hasAlpha = cairoImage->mHasAlpha; size = cairoImage->mSize; } if (hasAlpha) { if (mFilter == gfxPattern::FILTER_NEAREST) { technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint"); } else { technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); } } else { if (mFilter == gfxPattern::FILTER_NEAREST) { technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint"); } else { technique = effect()->GetTechniqueByName("RenderRGBLayerPremul"); } } if (srView) { effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView); } effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( (float)0, (float)0, (float)size.width, (float)size.height) ); } else if (image->GetFormat() == Image::PLANAR_YCBCR) { PlanarYCbCrImageD3D10 *yuvImage = static_cast<PlanarYCbCrImageD3D10*>(image.get()); if (!yuvImage->HasData()) { return; } if (yuvImage->mDevice != device()) { // These shader resources were created for an old device! Can't draw // that here. return; } // TODO: At some point we should try to deal with mFilter here, you don't // really want to use point filtering in the case of NEAREST, since that // would also use point filtering for Chroma upsampling. Where most likely // the user would only want point filtering for final RGB image upsampling. technique = effect()->GetTechniqueByName("RenderYCbCrLayer"); effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(yuvImage->mYView); effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(yuvImage->mCbView); effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(yuvImage->mCrView); /* * Send 3d control data and metadata to NV3DVUtils */ if (GetNv3DVUtils()) { Nv_Stereo_Mode mode; switch (yuvImage->mData.mStereoMode) { case STEREO_MODE_LEFT_RIGHT: mode = NV_STEREO_MODE_LEFT_RIGHT; break; case STEREO_MODE_RIGHT_LEFT: mode = NV_STEREO_MODE_RIGHT_LEFT; break; case STEREO_MODE_BOTTOM_TOP: mode = NV_STEREO_MODE_BOTTOM_TOP; break; case STEREO_MODE_TOP_BOTTOM: mode = NV_STEREO_MODE_TOP_BOTTOM; break; case STEREO_MODE_MONO: mode = NV_STEREO_MODE_MONO; break; } // Send control data even in mono case so driver knows to leave stereo mode. GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE); if (yuvImage->mData.mStereoMode != STEREO_MODE_MONO) { // Dst resource is optional GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->mSize.width, (unsigned int)yuvImage->mSize.height, (HANDLE)(yuvImage->mYTexture), (HANDLE)(NULL)); } } effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( (float)0, (float)0, (float)yuvImage->mSize.width, (float)yuvImage->mSize.height) ); } technique->GetPassByIndex(0)->Apply(0); device()->Draw(4, 0); }
void ImageLayerD3D10::RenderLayer() { ImageContainer *container = GetContainer(); if (!container) { return; } AutoLockImage autoLock(container); Image *image = autoLock.GetImage(); if (!image) { return; } gfxIntSize size = mScaleMode == SCALE_NONE ? image->GetSize() : mScaleToSize; SetEffectTransformAndOpacity(); ID3D10EffectTechnique *technique; if (image->GetFormat() == Image::CAIRO_SURFACE || image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { bool hasAlpha = false; if (image->GetFormat() == Image::REMOTE_IMAGE_BITMAP) { RemoteBitmapImage *remoteImage = static_cast<RemoteBitmapImage*>(image); if (!image->GetBackendData(LayerManager::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat = new TextureD3D10BackendData(); dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); image->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); } } hasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32; } else { CairoImage *cairoImage = static_cast<CairoImage*>(image); if (!cairoImage->mSurface) { return; } if (!image->GetBackendData(LayerManager::LAYERS_D3D10)) { nsAutoPtr<TextureD3D10BackendData> dat = new TextureD3D10BackendData(); dat->mTexture = SurfaceToTexture(device(), cairoImage->mSurface, cairoImage->mSize); if (dat->mTexture) { device()->CreateShaderResourceView(dat->mTexture, NULL, getter_AddRefs(dat->mSRView)); image->SetBackendData(LayerManager::LAYERS_D3D10, dat.forget()); } } hasAlpha = cairoImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA; } TextureD3D10BackendData *data = static_cast<TextureD3D10BackendData*>(image->GetBackendData(LayerManager::LAYERS_D3D10)); if (!data) { return; } nsRefPtr<ID3D10Device> dev; data->mTexture->GetDevice(getter_AddRefs(dev)); if (dev != device()) { return; } if (hasAlpha) { if (mFilter == gfxPattern::FILTER_NEAREST) { technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint"); } else { technique = effect()->GetTechniqueByName("RenderRGBALayerPremul"); } } else { if (mFilter == gfxPattern::FILTER_NEAREST) { technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint"); } else { technique = effect()->GetTechniqueByName("RenderRGBLayerPremul"); } } effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(data->mSRView); effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( (float)0, (float)0, (float)size.width, (float)size.height) ); } else if (image->GetFormat() == Image::PLANAR_YCBCR) { PlanarYCbCrImage *yuvImage = static_cast<PlanarYCbCrImage*>(image); if (!yuvImage->mBufferSize) { return; } if (!yuvImage->GetBackendData(LayerManager::LAYERS_D3D10)) { AllocateTexturesYCbCr(yuvImage); } PlanarYCbCrD3D10BackendData *data = static_cast<PlanarYCbCrD3D10BackendData*>(yuvImage->GetBackendData(LayerManager::LAYERS_D3D10)); if (!data) { return; } nsRefPtr<ID3D10Device> dev; data->mYTexture->GetDevice(getter_AddRefs(dev)); if (dev != device()) { return; } // TODO: At some point we should try to deal with mFilter here, you don't // really want to use point filtering in the case of NEAREST, since that // would also use point filtering for Chroma upsampling. Where most likely // the user would only want point filtering for final RGB image upsampling. technique = effect()->GetTechniqueByName("RenderYCbCrLayer"); effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(data->mYView); effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(data->mCbView); effect()->GetVariableByName("tCr")->AsShaderResource()->SetResource(data->mCrView); /* * Send 3d control data and metadata to NV3DVUtils */ if (GetNv3DVUtils()) { Nv_Stereo_Mode mode; switch (yuvImage->mData.mStereoMode) { case STEREO_MODE_LEFT_RIGHT: mode = NV_STEREO_MODE_LEFT_RIGHT; break; case STEREO_MODE_RIGHT_LEFT: mode = NV_STEREO_MODE_RIGHT_LEFT; break; case STEREO_MODE_BOTTOM_TOP: mode = NV_STEREO_MODE_BOTTOM_TOP; break; case STEREO_MODE_TOP_BOTTOM: mode = NV_STEREO_MODE_TOP_BOTTOM; break; case STEREO_MODE_MONO: mode = NV_STEREO_MODE_MONO; break; } // Send control data even in mono case so driver knows to leave stereo mode. GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE); if (yuvImage->mData.mStereoMode != STEREO_MODE_MONO) { // Dst resource is optional GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->mSize.width, (unsigned int)yuvImage->mSize.height, (HANDLE)(data->mYTexture), (HANDLE)(NULL)); } } effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( (float)0, (float)0, (float)size.width, (float)size.height) ); effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector( ShaderConstantRectD3D10( (float)yuvImage->mData.mPicX / yuvImage->mData.mYSize.width, (float)yuvImage->mData.mPicY / yuvImage->mData.mYSize.height, (float)yuvImage->mData.mPicSize.width / yuvImage->mData.mYSize.width, (float)yuvImage->mData.mPicSize.height / yuvImage->mData.mYSize.height) ); } bool resetTexCoords = image->GetFormat() == Image::PLANAR_YCBCR; image = nsnull; autoLock.Unlock(); technique->GetPassByIndex(0)->Apply(0); device()->Draw(4, 0); if (resetTexCoords) { effect()->GetVariableByName("vTextureCoords")->AsVector()-> SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f)); } GetContainer()->NotifyPaintedImage(image); }