bool StWinHandles::destroyWindow(HWND& theWindow) { if(theWindow != NULL) { if(DestroyWindow(theWindow) == 0) { ST_DEBUG_LOG("WinAPI, FAILED to destroy the Window"); return false; } ST_DEBUG_LOG("WinAPI, Destroyed window"); theWindow = NULL; } return true; }
bool StWinHandles::unregisterClass(StStringUtfWide& theName) { HMODULE aModule = GetModuleHandleW(NULL); if(!theName.isEmpty()) { if(UnregisterClassW(theName.toCString(), aModule) == 0) { ST_DEBUG_LOG("WinAPI, FAILED to unregister Class= '" + theName.toUtf8() + "'"); return false; } ST_DEBUG_LOG("WinAPI, Unregistered Class= " + theName.toUtf8()); theName.clear(); } return true; }
/** * Return color conversion shader part from StImage definition. */ static inline StGLImageProgram::FragToRgb getColorShader(const StImage::ImgColorModel theColorModel, const StImage::ImgColorScale theColorScale) { switch(theColorModel) { case StImage::ImgColor_RGB: return StGLImageProgram::FragToRgb_FromRgb; case StImage::ImgColor_RGBA: return StGLImageProgram::FragToRgb_FromRgba; case StImage::ImgColor_GRAY: return StGLImageProgram::FragToRgb_FromGray; case StImage::ImgColor_XYZ: return StGLImageProgram::FragToRgb_FromXyz; case StImage::ImgColor_YUV: { switch(theColorScale) { case StImage::ImgScale_Mpeg9: return StGLImageProgram::FragToRgb_FromYuv9Mpeg; case StImage::ImgScale_Mpeg10: return StGLImageProgram::FragToRgb_FromYuv10Mpeg; case StImage::ImgScale_Jpeg9: return StGLImageProgram::FragToRgb_FromYuv9Full; case StImage::ImgScale_Jpeg10: return StGLImageProgram::FragToRgb_FromYuv10Full; case StImage::ImgScale_Mpeg: return StGLImageProgram::FragToRgb_FromYuvMpeg; case StImage::ImgScale_Full: return StGLImageProgram::FragToRgb_FromYuvFull; case StImage::ImgScale_NvMpeg: return StGLImageProgram::FragToRgb_FromYuvNvMpeg; case StImage::ImgScale_NvFull: return StGLImageProgram::FragToRgb_FromYuvNvFull; } return StGLImageProgram::FragToRgb_FromYuvFull; } default: { ST_DEBUG_LOG("No GLSL shader for this color model = " + theColorModel); ST_ASSERT(false, "StGLImageProgram::getColorShader() - unsupported color model!"); } } return StGLImageProgram::FragToRgb_FromRgb; }
/** * Convert image from one format to another using swscale. * Image buffers should be already initialized! */ static bool convert(const StImage& theImageFrom, PixelFormat theFormatFrom, StImage& theImageTo, PixelFormat theFormatTo) { ST_DEBUG_LOG("StAVImage, convert from " + stAV::PIX_FMT::getString(theFormatFrom) + " " + theImageFrom.getSizeX() + "x" + theImageFrom.getSizeY() + " to " + stAV::PIX_FMT::getString(theFormatTo) + " " + theImageTo.getSizeX() + "x" + theImageTo.getSizeY()); SwsContext* aCtxToRgb = sws_getContext((int )theImageFrom.getSizeX(), (int )theImageFrom.getSizeY(), theFormatFrom, // source (int )theImageTo.getSizeX(), (int )theImageTo.getSizeY(), theFormatTo, // destination SWS_BICUBIC, NULL, NULL, NULL); if(aCtxToRgb == NULL) { return false; } uint8_t* aSrcData[4]; int aSrcLinesize[4]; fillPointersAV(theImageFrom, aSrcData, aSrcLinesize); uint8_t* aDstData[4]; int aDstLinesize[4]; fillPointersAV(theImageTo, aDstData, aDstLinesize); sws_scale(aCtxToRgb, aSrcData, aSrcLinesize, 0, (int )theImageFrom.getSizeY(), aDstData, aDstLinesize); sws_freeContext(aCtxToRgb); return true; }
bool StGLStereoFrameBuffer::initLazy(StGLContext& theCtx, const GLsizei theSizeX, const GLsizei theSizeY, const bool theNeedDepthBuffer, const bool theToCompress) { if(isValid() && (theSizeX <= getSizeX() && getSizeX() < theCtx.getMaxTextureSize()) && (theSizeY <= getSizeY() && getSizeY() < theCtx.getMaxTextureSize())) { if(!theToCompress || (((getSizeX() - theSizeX) < 256) && ((getSizeY() - theSizeY) < 256))) { setVPDimensions(theCtx, theSizeX, theSizeY); return true; } } release(theCtx); GLsizei aSizeX = stMax(32, (GLsizei )getAligned(theSizeX, 256)); GLsizei aSizeY = stMax(32, (GLsizei )getAligned(theSizeY, 256)); if(!theCtx.arbNPTW) { StGLFrameBuffer::convertToPowerOfTwo(theCtx, aSizeX, aSizeY); } if(!init(theCtx, aSizeX, aSizeY, theNeedDepthBuffer)) { return false; } theCtx.stglFillBitsFBO(myGLFBufferIds[StGLStereoTexture::LEFT_TEXTURE], aSizeX, aSizeY); ST_DEBUG_LOG("FBO resized to " + aSizeX + " x " + aSizeY + " (for " + theSizeX + " x " + theSizeY + ")"); setVPDimensions(theCtx, theSizeX, theSizeY); return true; }
/** * Our own XError handle function. * Default handlers just show the error and exit application immediately. * This is very horrible for application, because many errors not critical and could be ignored. * The main target for this function creation - prevent sView to quit after * multiple BadMatch errors happens on fullscreen->windowed switching * (looking like a vendors OpenGL driver bug). * Thus, now we just show up the error description and just ignore it - hopes we will well. * Function behaviour could be extended in future. */ int stXErrorHandler(Display* theDisplay, XErrorEvent* theErrorEvent) { char aBuffer[4096]; XGetErrorText(theDisplay, theErrorEvent->error_code, aBuffer, 4096); ST_DEBUG_LOG("XError happend: " + aBuffer + "; ignored"); // have no idea WHAT we should return here.... return 0; }
void StGLWidget::setClicked(const int& mouseBtn, bool isClicked) { if(mouseBtn > ST_MOUSE_MAX_ID) { // ignore out of range buttons ST_DEBUG_LOG("StGLWidget, mouse button click #" + mouseBtn + " ignored!"); return; } mouseClicked[mouseBtn] = isClicked; }
bool StADLsdk::init() { // reset state close(); if(!myLib.load(LIB_NAME)) { #if(defined(_WIN32) || defined(__WIN32__)) \ && !defined(WIN64) && !defined(_WIN64) && !defined(__WIN64__) // library in WOW64, only for 32-bit application under 64-bit Windows if(!myLib.load(LIB_NAME_Y)) { return false; } #elif(defined(__linux__) || defined(__linux)) return false; #endif } myLib("ADL_Main_Control_Create", myFunctions.ADL_Main_Control_Create); myLib("ADL_Main_Control_Destroy", myFunctions.ADL_Main_Control_Destroy); // The second parameter is 0, which means: // retrieve adapter information only for adapters that are physically present and enabled in the system if(myFunctions.ADL_Main_Control_Create == NULL || myFunctions.ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 0) != ADL_OK) { ST_DEBUG_LOG("StADLsdk, library Initialization error!"); close(); return false; } myLib("ADL_Adapter_NumberOfAdapters_Get", myFunctions.ADL_Adapter_NumberOfAdapters_Get); myLib("ADL_Display_DisplayInfo_Get", myFunctions.ADL_Display_DisplayInfo_Get); myLib("ADL_Adapter_AdapterInfo_Get", myFunctions.ADL_Adapter_AdapterInfo_Get); myLib("ADL_Adapter_Active_Get", myFunctions.ADL_Adapter_Active_Get); myLib("ADL_Display_ColorCaps_Get", myFunctions.ADL_Display_ColorCaps_Get); myLib("ADL_Display_Color_Get", myFunctions.ADL_Display_Color_Get); myLib("ADL_Display_Color_Set", myFunctions.ADL_Display_Color_Set); myLib("ADL_Display_Position_Get", myFunctions.ADL_Display_Position_Get); myLib("ADL_Display_Position_Set", myFunctions.ADL_Display_Position_Set); myLib("ADL_Display_ModeTimingOverride_Get", myFunctions.ADL_Display_ModeTimingOverride_Get); myLib("ADL_Display_EdidData_Get", myFunctions.ADL_Display_EdidData_Get); myLib("ADL_Display_WriteAndReadI2C", myFunctions.ADL_Display_WriteAndReadI2C); myLib("ADL_Display_DDCInfo_Get", myFunctions.ADL_Display_DDCInfo_Get); #if(defined(__linux__) || defined(__linux)) myLib("ADL_DesktopConfig_Get", myFunctions.ADL_DesktopConfig_Get); myLib("ADL_DesktopConfig_Set", myFunctions.ADL_DesktopConfig_Set); #endif if(!countAdapters() || myFunctions.ADL_Adapter_NumberOfAdapters_Get == NULL || myFunctions.ADL_Adapter_AdapterInfo_Get == NULL || myFunctions.ADL_Display_DisplayInfo_Get == NULL || myFunctions.ADL_Adapter_Active_Get == NULL) { // no AMD adapters... close(); return false; } return true; }
StWinGlrc::~StWinGlrc() { if(myRC == NULL) { return; } // release active context if(!glXMakeCurrent(myDisplay, None, NULL)) { ST_DEBUG_LOG("X, FAILED to release OpenGL context"); } glXDestroyContext(myDisplay, myRC); }
bool StDXManager::swap() { if(myD3dDevice == NULL) { return false; } const HRESULT isOK = myD3dDevice->Present(NULL, NULL, NULL, NULL); if(isOK != D3D_OK) { ST_DEBUG_LOG("Direct3D9, Present device failed, " + printErrorDesc(isOK)); } return isOK == D3D_OK; }
StGLVarLocation StGLProgram::getUniformLocation(StGLContext& theCtx, const char* theVarName) const { if(!isValid()) { return StGLVarLocation(); } const StGLVarLocation aLocation(theCtx.core20fwd->glGetUniformLocation(myProgramId, theVarName)); #ifdef __ST_DEBUG__ if(!aLocation.isValid()) { ST_DEBUG_LOG("Warning! Uniform variable '" + theVarName + "' doesn't found in the whole shader!"); } #endif return aLocation; }
HMODULE StLibrary::DLibLoadFull(const StString& theLibName) { #ifdef _WIN32 HMODULE aModule = LoadLibraryW(theLibName.toUtfWide().toCString()); if(aModule == NULL) { ST_DEBUG_LOG("Failed to load library: \"" + theLibName + "\" (" + (int )GetLastError() + ')'); } else { #ifdef ST_DEBUG_LIBS ST_DEBUG_LOG("Loaded library: \"" + theLibName + "\" " + DLibGetVersion(theLibName.toUtfWide())); #endif } return aModule; #else HMODULE aModule = dlopen(theLibName.toCString(), RTLD_NOW); if(aModule == NULL) { ST_DEBUG_LOG("Failed to load library: \"" + theLibName + "\" (" + dlerror() + ')'); } else { #ifdef ST_DEBUG_LIBS ST_DEBUG_LOG("Loaded library: \"" + theLibName + '\"'); #endif } return aModule; #endif }
void StProcess::openURL(const StString& theUrl) { #if defined(_WIN32) ShellExecuteW(NULL, L"open", theUrl.toUtfWide().toCString(), NULL, NULL, SW_SHOWNORMAL); #elif(defined(__linux__) || defined(__linux)) // we use nice script tool from Xdg-utils package // http://portland.freedesktop.org/wiki/ StArrayList<StString> anArguments(1); anArguments.add(theUrl); if(!StProcess::execProcess("/usr/bin/xdg-open", anArguments)) { ST_DEBUG_LOG("/usr/bin/xdg-open is not found!"); } // also we could use GTK function //gtk_show_uri(NULL, uri, gtk_get_current_event_time(), &err); #endif }
void StGLFrameTextures::increaseSize(StGLContext& theCtx, StGLFrameTexture& theTexture, const GLsizei theTextureSizeX, const GLsizei theTextureSizeY) { // test existing size / new size /// TODO (Kirill Gavrilov#8) we can automatically reduce texture size here if((theTexture.getSizeX() < theTextureSizeX) || (theTexture.getSizeY() < theTextureSizeY) || !theTexture.isValid()) { ST_DEBUG_LOG("Requested texture size (" + theTextureSizeX + 'x' + theTextureSizeY + ") larger than current texture size(" + theTexture.getSizeX() + 'x' + theTexture.getSizeY() + ')'); const GLsizei anOriginalSizeX = theTexture.getSizeX(); const GLsizei anOriginalSizeY = theTexture.getSizeY(); const GLint aMaxTexDim = theCtx.getMaxTextureSize(); GLsizei aNewSizeX = stMin(theTextureSizeX, GLsizei(aMaxTexDim)); GLsizei aNewSizeY = stMin(theTextureSizeY, GLsizei(aMaxTexDim)); if(!theCtx.arbNPTW) { aNewSizeX = getPowerOfTwo(theTextureSizeX, GLsizei(aMaxTexDim)); aNewSizeY = getPowerOfTwo(theTextureSizeY, GLsizei(aMaxTexDim)); } if((aNewSizeY != anOriginalSizeY) || (aNewSizeX != anOriginalSizeX)) { if(!theTexture.initTrash(theCtx, aNewSizeX, aNewSizeY)) { theTexture.initTrash(theCtx, (anOriginalSizeX > 0) ? anOriginalSizeX : 512, (anOriginalSizeY > 0) ? anOriginalSizeY : 512); ST_DEBUG_LOG("FAILED to Increase the texture size to (" + aNewSizeX + 'x' + aNewSizeY + ")!"); } else { ST_DEBUG_LOG("Increase the texture size to (" + aNewSizeX + 'x' + aNewSizeY + ") success!"); } } else { ST_DEBUG_LOG("Not possible to Increase the texture size!"); } } }
StWinGlrc::~StWinGlrc() { if(myRC != EGL_NO_CONTEXT) { if(eglMakeCurrent(myDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { ST_DEBUG_LOG("EGL, FAILED to release OpenGL context"); } eglDestroyContext(myDisplay, myRC); myRC = EGL_NO_CONTEXT; } if(myDisplay != EGL_NO_DISPLAY) { if(eglTerminate(myDisplay) != EGL_TRUE) { ST_ERROR_LOG("EGL, eglTerminate FAILED"); } myDisplay = EGL_NO_DISPLAY; } }
bool StDXManager::reset(const HWND theWinHandle, const int theSizeX, const int theSizeY, const bool theFullscreen) { if(myD3dDevice == NULL) { return false; } myD3dParams.Windowed = !theFullscreen; // is windowed? myD3dParams.BackBufferWidth = theSizeX; myD3dParams.BackBufferHeight = theSizeY; myD3dParams.hDeviceWindow = theWinHandle; myD3dParams.FullScreen_RefreshRateInHz = theFullscreen ? myRefreshRate : 0; HRESULT isOK = myD3dDevice->Reset(&myD3dParams); ST_DEBUG_LOG("Direct3D9, Reset device (" + printDisplayFormat(myD3dParams) + "), " + printErrorDesc(isOK)); return isOK == D3D_OK; }
bool StGLProgram::link(StGLContext& theCtx) { if(!isValid()) { return false; } theCtx.core20fwd->glLinkProgram(myProgramId); // if linkage failed - automatically remove the program! if(!isLinked(theCtx)) { theCtx.pushError(StString("Linking of the program '") + myTitle + "' failed!\n" + getLinkageInfo(theCtx)); release(theCtx); return false; } #ifdef __ST_DEBUG_SHADERS__ const StString anInfo = getLinkageInfo(theCtx); ST_DEBUG_LOG("Program '" + myTitle + "' has been linked" + (!anInfo.isEmpty() ? (StString(". Log:\n") + anInfo) : (StString()))); #endif return true; }
int StApplication::exec() { if(!myIsOpened) { if(!open()) { return 1; } } if(!myWindow.isNull()) { // just debug output Monitors' configuration const StSearchMonitors& aMonitors = myWindow->getMonitors(); for(size_t aMonIter = 0; aMonIter < aMonitors.size(); ++aMonIter) { ST_DEBUG_LOG(aMonitors[aMonIter].toString()); } } for(; !myWindow.isNull() && myIsOpened;) { processEvents(); } return myExitCode; }
void StAndroidGlue::printConfig() { char aLang[3], aCountry[3]; AConfiguration_getLanguage(myConfig, aLang); AConfiguration_getCountry (myConfig, aCountry); aLang[2] = '\0'; aCountry[2] = '\0'; ST_DEBUG_LOG("Config:" + " mcc=" + AConfiguration_getMcc(myConfig) + " mnc=" + AConfiguration_getMnc(myConfig) + " lang=" + aLang + " cnt=" + aCountry + " orien=" + AConfiguration_getOrientation(myConfig) + " touch=" + AConfiguration_getTouchscreen(myConfig) + " dens=" + AConfiguration_getDensity (myConfig) + " keys=" + AConfiguration_getKeyboard (myConfig) + " nav=" + AConfiguration_getNavigation (myConfig) + " keysHid=" + AConfiguration_getKeysHidden (myConfig) + " navHid=" + AConfiguration_getNavHidden (myConfig) + " sdk=" + AConfiguration_getSdkVersion (myConfig) + " size=" + AConfiguration_getScreenSize (myConfig) + " long=" + AConfiguration_getScreenLong (myConfig) + " modetype=" + AConfiguration_getUiModeType (myConfig) + " modenight=" + AConfiguration_getUiModeNight(myConfig)); }
IDirect3DDevice9* StDXManager::createAqbsTmpDevice(const UINT theAdapterId, const HWND theWinHandle, const D3DPRESENT_PARAMETERS& theD3dParams) { // first create a temporary windowed device IDirect3DDevice9* aD3dDevTmp = NULL; D3DPRESENT_PARAMETERS aD3dParamsTmp = theD3dParams; aD3dParamsTmp.Windowed = TRUE; aD3dParamsTmp.SwapEffect = D3DSWAPEFFECT_COPY; aD3dParamsTmp.BackBufferCount = 1; aD3dParamsTmp.BackBufferWidth = 2; aD3dParamsTmp.BackBufferHeight = 2; aD3dParamsTmp.EnableAutoDepthStencil = FALSE; aD3dParamsTmp.Flags = 0; aD3dParamsTmp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; aD3dParamsTmp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; aD3dParamsTmp.MultiSampleType = D3DMULTISAMPLE_NONE; if(myD3dLib->CreateDevice(theAdapterId, D3DDEVTYPE_HAL, theWinHandle, ST_D3D_DEVICE_FLAGS, &aD3dParamsTmp, &aD3dDevTmp) < 0) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), failed to create temporary D3D device"); return NULL; } return aD3dDevTmp; }
bool StLangMap::open(const StString& theLngFilePath) { myLngFile = theLngFilePath; #ifdef _WIN32 // it is possible to use std::ifstream, but only for ANSI filenames HANDLE inFile = CreateFileW(myLngFile.toUtfWide().toCString(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(inFile == INVALID_HANDLE_VALUE) { ST_DEBUG_LOG("StLangMap, Failed to open language file \"" + myLngFile + '\"'); return false; } #else std::ifstream inFile; inFile.open(myLngFile.toCString()); if(inFile.fail()) { ST_DEBUG_LOG("StLangMap, Failed to open language file \"" + myLngFile + '\"'); return false; } #endif char bufferOrig[READ_BUFFER_SIZE]; bufferOrig[0] = '\0'; char* bufferLineOrig = new char[1]; bufferLineOrig[0] = '\0'; size_t aLineSize = 0; StString bufferLineUTF; bool isCont = false; size_t oldLen = 0; #ifdef _WIN32 DWORD aBytesRead = 0; while(ReadFile(inFile, bufferOrig, READ_BUFFER_SIZE, &aBytesRead, NULL)) { if(aBytesRead < 1) { break; } #else while(!inFile.eof()) { inFile.read(bufferOrig, READ_BUFFER_SIZE); const size_t aBytesRead = inFile.gcount(); if(aBytesRead < 1) { break; } #endif size_t lineStart = 0; for(size_t c = 0; c < (size_t )aBytesRead; ++c) { if(bufferOrig[c] == '\n') { if(isCont) { char* aCopy = new char[oldLen + c - lineStart + 1]; stMemCpy(&aCopy[0], bufferLineOrig, oldLen); stMemCpy(&aCopy[oldLen], &bufferOrig[lineStart], (c - lineStart)); aLineSize = oldLen + c - lineStart; delete[] bufferLineOrig; bufferLineOrig = aCopy; } else { delete[] bufferLineOrig; bufferLineOrig = new char[c - lineStart + 1]; stMemCpy(bufferLineOrig, &bufferOrig[lineStart], (c - lineStart)); aLineSize = c - lineStart; } // remove CR symbol if needed if(aLineSize > 0 && bufferLineOrig[aLineSize - 1] == stUtf8_t(13)) { --aLineSize; } bufferLineOrig[aLineSize] = '\0'; bufferLineUTF = StString(bufferLineOrig); parseLine(bufferLineUTF); lineStart = c + 1; oldLen = 0; isCont = false; } else if(c == (READ_BUFFER_SIZE - 1)) { char* aCopy = new char[oldLen + READ_BUFFER_SIZE - lineStart]; if(oldLen > 0) { stMemCpy(aCopy, bufferLineOrig, oldLen); } stMemCpy(&aCopy[oldLen], &bufferOrig[lineStart], (READ_BUFFER_SIZE - lineStart)); delete[] bufferLineOrig; bufferLineOrig = aCopy; oldLen += (READ_BUFFER_SIZE - lineStart); isCont = true; } if(!isCont) { delete[] bufferLineOrig; bufferLineOrig = new char[1]; bufferLineOrig[0] = '\0'; } } } delete[] bufferLineOrig; #ifdef _WIN32 CloseHandle(inFile); #else inFile.close(); #endif ST_DEBUG_LOG("StLangMap, Loaded language file \"" + myLngFile + '\"'); return true; } StString& StLangMap::changeValue(const size_t theId) { return myMap[theId]; } const StString& StLangMap::getValue(const size_t theId) const { const std::map<size_t, StString>::const_iterator anIter = myMap.find(theId); return (anIter != myMap.end()) ? anIter->second : myEmptyStr; } StString& StLangMap::changeValueId(const size_t theId, const char* theDefaultValue) { StString& aValue = myMap[theId]; if(aValue.isEmpty()) { if(myToShowId) { aValue = StString('[') + theId + ']' + theDefaultValue; } else { aValue = theDefaultValue; } } return aValue; }
bool StPlayList::walkToNext(const bool theToForce) { StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL || (myToLoopSingle && !theToForce)) { return false; } else if(myIsShuffle && myItemsCount >= 3) { StPlayItem* aPrev = myCurrent; if(!myStackNext.empty()) { myCurrent = myStackNext.front(); myStackNext.pop_front(); } else { if((myPlayedCount >= (myItemsCount - 1)) || (myPlayedCount == 0)) { // reset the playback counter #ifdef _WIN32 FILETIME aTime; GetSystemTimeAsFileTime(&aTime); myRandGen.setSeed(aTime.dwLowDateTime); #else timeval aTime; gettimeofday(&aTime, NULL); myRandGen.setSeed(aTime.tv_usec); #endif myPlayedCount = 0; myCurrent->setPlayedFlag(!myCurrent->getPlayedFlag()); ST_DEBUG_LOG("Restart the shuffle"); } // determine next random position const size_t aCurrPos = myCurrent->getPosition(); bool aCurrFlag = myCurrent->getPlayedFlag(); StPlayItem* aNextItem = myCurrent; const size_t aNextPos = stMin(size_t(myRandGen.next() * myItemsCount), myItemsCount - 1); if(aNextPos > aCurrPos) { // forward direction for(size_t aNextDiff = aNextPos - aCurrPos; aNextItem != NULL && aNextDiff != 0; --aNextDiff) { aNextItem = aNextItem->getNext(); } } else { // backward direction for(size_t aNextDiff = aCurrPos - aNextPos; aNextItem != NULL && aNextDiff != 0; --aNextDiff) { aNextItem = aNextItem->getPrev(); } } if(aCurrFlag == aNextItem->getPlayedFlag()) { // find nearest position not yet played - prefer item farther from current one StPlayItem* aNextItem1 = aNextPos > aCurrPos ? aNextItem->getNext() : aNextItem->getPrev(); StPlayItem* aNextItem2 = aNextPos > aCurrPos ? aNextItem->getPrev() : aNextItem->getNext(); for(; aNextItem1 != NULL || aNextItem2 != NULL;) { if(aNextItem1 != NULL) { if(aCurrFlag != aNextItem1->getPlayedFlag()) { aNextItem = aNextItem1; break; } aNextItem1 = aNextPos > aCurrPos ? aNextItem1->getNext() : aNextItem1->getPrev(); } if(aNextItem2 != NULL) { if(aCurrFlag != aNextItem2->getPlayedFlag()) { aNextItem = aNextItem2; break; } aNextItem2 = aNextPos > aCurrPos ? aNextItem2->getPrev() : aNextItem2->getNext(); } } if(aCurrFlag == aNextItem->getPlayedFlag()) { // something wrong! ST_DEBUG_LOG("Disaster - next shuffle position not found!"); aCurrFlag = !aCurrFlag; myPlayedCount = 0; } } ST_DEBUG_LOG(aCurrPos + " -> " + aNextItem->getPosition()); ++myPlayedCount; aNextItem->setPlayedFlag(aCurrFlag); myCurrent = aNextItem; } if(aPrev != myCurrent && aPrev != NULL) { myStackPrev.push_back(aPrev); if(myStackPrev.size() > THE_UNDO_LIMIT) { myStackPrev.pop_front(); } } const size_t anItemId = myCurrent->getPosition(); anAutoLock.unlock(); signals.onPositionChange(anItemId); return true; } else if(myCurrent != myLast) { myCurrent = myCurrent->getNext(); const size_t anItemId = myCurrent->getPosition(); anAutoLock.unlock(); signals.onPositionChange(anItemId); return true; } else if(myIsLoopFlag) { return walkToFirst(); } return false; }
StLogContext::~StLogContext() { ST_DEBUG_LOG(" == Process " + StProcess::getProcessName() + " (" + StProcess::getPID() + "), module " + myName + " Unloaded =="); }
StLogContext::StLogContext(const char* theName) : myName(theName) { ST_DEBUG_LOG(" == Process " + StProcess::getProcessName() + " (" + StProcess::getPID() + "), module " + myName + " Loaded =="); }
bool StDXManager::init(const HWND theWinHandle, const int theSizeX, const int theSizeY, const bool theFullscreen, const StMonitor& theMonitor, const StDXAdapterClass theAdapter) { const StString anAdapterStr = theMonitor.getName().subString(0, 12); if(!initDxLib()) { stError("StDXManager, Direct3DCreate9 failed!"); return false; } const UINT aD3dAdaptersNb = getAdapterCount(); UINT anAdapterId = UINT(-1); UINT anAdapterVendor = UINT(-1); D3DADAPTER_IDENTIFIER9 anAdapterInfo; for(UINT anAdapterIter = 0; anAdapterIter < aD3dAdaptersNb; ++anAdapterIter) { getAdapterIdentifier(anAdapterIter, 0, &anAdapterInfo); switch(theAdapter) { case ST_DX_ADAPTER_AMD: { if(anAdapterInfo.VendorId != ST_DX_VENDOR_AMD) { continue; } anAdapterVendor = anAdapterIter; break; } case ST_DX_ADAPTER_NVIDIA: { if(anAdapterInfo.VendorId != ST_DX_VENDOR_NVIDIA) { continue; } anAdapterVendor = anAdapterIter; break; } case ST_DX_ADAPTER_ANY: default: break; } if(anAdapterStr == StString(anAdapterInfo.DeviceName)) { anAdapterId = anAdapterIter; break; } } if(theAdapter != ST_DX_ADAPTER_ANY) { if(anAdapterId == UINT(-1) && anAdapterVendor != UINT(-1)) { anAdapterId = anAdapterVendor; } if(anAdapterId == UINT(-1)) { return false; } } if(anAdapterId == UINT(-1)) { // the default adapter is the primary display adapter anAdapterId = D3DADAPTER_DEFAULT; } // setup the present parameters if(getAdapterDisplayMode(anAdapterId, &myCurrMode) == D3D_OK) { myD3dParams.BackBufferFormat = myCurrMode.Format; myRefreshRate = myCurrMode.RefreshRate; } myD3dParams.Windowed = !theFullscreen; // is windowed? myD3dParams.BackBufferWidth = theSizeX; myD3dParams.BackBufferHeight = theSizeY; myD3dParams.hDeviceWindow = theWinHandle; // create the Video Device myD3dDevice = createAqbsDevice(anAdapterId, theWinHandle, myD3dParams); if(myD3dDevice == NULL) { HRESULT isOK = myD3dLib->CreateDevice(anAdapterId, D3DDEVTYPE_HAL, // the HAL (hardware accelerated layer) uses your 3d accelerator card theWinHandle, ST_D3D_DEVICE_FLAGS, &myD3dParams, &myD3dDevice); if(isOK < 0) { return false; } } // this normalizes the normal values (this is important for how lighting effects your models) ///myD3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); ST_DEBUG_LOG("Direct3D9, Created StDXManager device (WxH= " + theSizeX + "x"+ theSizeY + ")"); return myD3dDevice != NULL; }
bool StWinHandles::close() { #ifdef _WIN32 // NOTE - destroy functions will fail if called from another thread than created const size_t aThreadId = StThread::getCurrentThreadId(); myMutex.lock(); // ========= Release OpenGL resources ========= if(aThreadId == ThreadGL && hWindowGl != NULL) { ST_DEBUG_LOG("WinAPI, close, aThreadId= " + aThreadId + ", ThreadGL= " + ThreadGL + ", ThreadWnd= " + ThreadWnd); // release Rendering Context hRC.nullify(); // Release Device Context if(hDC != NULL && hWindowGl != NULL) { if(ReleaseDC(hWindowGl, hDC) == 0) { ST_DEBUG_LOG("WinAPI, FAILED to release DC"); myMutex.unlock(); return false; } else { ST_DEBUG_LOG("WinAPI, Released DC"); hDC = NULL; ThreadGL = 0; } } } // release window resources if(aThreadId == ThreadWnd && hDC == NULL) { ST_DEBUG_LOG("WinAPI, close, aThreadId= " + aThreadId + ", ThreadGL= " + ThreadGL + ", ThreadWnd= " + ThreadWnd); // destroy windows if(!destroyWindow(hWindowGl) || !destroyWindow(hWindow) || !destroyWindow(hWinTmp)) { myMutex.unlock(); return false; } // unregister window classes if(hWindowGl == NULL && hWindow == NULL) { if(!unregisterClass(ClassGL) || !unregisterClass(ClassBase) || !unregisterClass(ClassTmp)) { myMutex.unlock(); return false; } } } myMutex.unlock(); #elif defined(__linux__) // release active context hRC.nullify(); if(!stXDisplay.isNull()) { // close x-server windows if(hWindowGl != 0) { XUnmapWindow(stXDisplay->hDisplay, hWindowGl); XDestroyWindow(stXDisplay->hDisplay, hWindowGl); hWindowGl = 0; } if(hWindow != 0) { XUnmapWindow(stXDisplay->hDisplay, hWindow); XDestroyWindow(stXDisplay->hDisplay, hWindow); hWindow = 0; } if(iconImage != 0) { XFreePixmap(stXDisplay->hDisplay, iconImage); iconImage = 0; } if(iconShape != 0) { XFreePixmap(stXDisplay->hDisplay, iconShape); iconShape = 0; } // close x-server connection stXDisplay.nullify(); } #endif return true; }
StWinHandles::StWinHandles() #ifdef _WIN32 : ThreadWnd(0), EventMsgThread(true), hWindow(NULL), hWindowGl(NULL), hWinTmp(NULL), myMKeyStop(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_STOP))), myMKeyPlay(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_PLAY_PAUSE))), myMKeyPrev(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_PREV_TRACK))), myMKeyNext(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_NEXT_TRACK))), ThreadGL(0), hDC(NULL) { // #elif defined(__linux__) : hWindow(0), hWindowGl(0), stXDisplay(), iconImage(0), iconShape(0), xDNDRequestType(None), xDNDSrcWindow(0), xDNDVersion(0), xrandrEventBase(0), isRecXRandrEvents(false) { // #endif } StWinHandles::~StWinHandles() { close(); } void StWinHandles::glSwap() { #ifdef _WIN32 if(hDC != NULL) { SwapBuffers(hDC); } #elif defined(__linux__) if(!stXDisplay.isNull() && hRC->makeCurrent(hWindowGl)) { // if GL rendering context is bound to another drawable - we got BadMatch error glXSwapBuffers(stXDisplay->hDisplay, hWindowGl); } #endif } bool StWinHandles::glMakeCurrent() { #ifdef _WIN32 if(hDC != NULL && !hRC.isNull()) { return hRC->isCurrent(hDC) || hRC->makeCurrent(hDC); } #elif defined(__linux__) if(!stXDisplay.isNull() && !hRC.isNull()) { return hRC->makeCurrent(hWindowGl); } #endif return false; } /** * Auxiliary macros. */ #define ST_GL_ERROR_CHECK(theTrueCondition, theErrCode, theErrDesc) \ if(!(theTrueCondition)) { \ stError(theErrDesc); \ return theErrCode; \ } int StWinHandles::glCreateContext(StWinHandles* theSlave, const StRectI_t& theRect, const int theDepthSize, const bool theIsQuadStereo, const bool theDebugCtx) { #ifdef _WIN32 ThreadGL = StThread::getCurrentThreadId(); ST_DEBUG_LOG("WinAPI, glCreateContext, ThreadGL= " + ThreadGL + ", ThreadWnd= " + ThreadWnd); hDC = GetDC(hWindowGl); ST_GL_ERROR_CHECK(hDC != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Can't create Master GL Device Context"); if(theSlave != NULL) { theSlave->ThreadGL = ThreadGL; theSlave->hDC = GetDC(theSlave->hWindowGl); ST_GL_ERROR_CHECK(theSlave->hDC != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Can't create Slave GL Device Context"); } PIXELFORMATDESCRIPTOR aPixFrmtDesc = THE_PIXELFRMT_DOUBLE; aPixFrmtDesc.cDepthBits = (BYTE )theDepthSize; if(theIsQuadStereo) { aPixFrmtDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO; } int aPixFrmtId = ChoosePixelFormat(hDC, &aPixFrmtDesc); ST_GL_ERROR_CHECK(aPixFrmtId != 0, STWIN_ERROR_WIN32_PIXELFORMATF, "WinAPI, Can't find a suitable PixelFormat for Master"); if(theSlave != NULL && ChoosePixelFormat(theSlave->hDC, &aPixFrmtDesc) != aPixFrmtId) { ST_ERROR_LOG("Slave window returns another pixel format! Try to ignore..."); } if(theIsQuadStereo) { DescribePixelFormat(hDC, aPixFrmtId, sizeof(PIXELFORMATDESCRIPTOR), &aPixFrmtDesc); if((aPixFrmtDesc.dwFlags & PFD_STEREO) == 0) { ST_ERROR_LOG("WinAPI, Quad Buffered stereo not supported"); } else { //bool isVistaPlus = StSys::isVistaPlus(); //bool isWin8Plus = StSys::isWin8Plus(); ///myNeedsFullscr } } HMODULE aModule = GetModuleHandleW(NULL); hWinTmp = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, ClassTmp.toCString(), L"TmpWnd", WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, theRect.left() + 2, theRect.top() + 2, 4, 4, NULL, NULL, aModule, NULL); ST_GL_ERROR_CHECK(hWinTmp != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Temporary window creation error"); HDC aDevCtxTmp = GetDC(hWinTmp); ST_GL_ERROR_CHECK(aPixFrmtId != 0, STWIN_ERROR_WIN32_PIXELFORMATF, "WinAPI, Can't find a suitable PixelFormat for Tmp"); ST_GL_ERROR_CHECK(SetPixelFormat(aDevCtxTmp, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Master"); StWinGlrcH aRendCtxTmp = new StWinGlrc(aDevCtxTmp, NULL); ST_GL_ERROR_CHECK(aRendCtxTmp->isValid(), STWIN_ERROR_WIN32_GLRC_CREATE, "WinAPI, Can't create GL Rendering Context"); ST_GL_ERROR_CHECK(aRendCtxTmp->makeCurrent(aDevCtxTmp), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Can't activate Tmp GL Rendering Context"); StGLContext aCtx; ST_GL_ERROR_CHECK(aCtx.stglInit(), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Broken Tmp GL Rendering Context"); if(aCtx.extAll->wglChoosePixelFormatARB != NULL) { const int aPixAttribs[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_STEREO_ARB, theIsQuadStereo ? GL_TRUE : GL_FALSE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, //WGL_SAMPLE_BUFFERS_ARB, 1, //WGL_SAMPLES_ARB, 8, // WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 WGL_COLOR_BITS_ARB, 24, WGL_DEPTH_BITS_ARB, theDepthSize, WGL_STENCIL_BITS_ARB, 0, 0, 0, }; unsigned int aFrmtsNb = 0; aCtx.extAll->wglChoosePixelFormatARB(hDC, aPixAttribs, NULL, 1, &aPixFrmtId, &aFrmtsNb); } ST_GL_ERROR_CHECK(SetPixelFormat(hDC, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Master"); ST_GL_ERROR_CHECK(theSlave == NULL || SetPixelFormat(theSlave->hDC, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Slave"); HGLRC aRendCtx = NULL; if(aCtx.extAll->wglCreateContextAttribsARB != NULL) { // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB int aCtxAttribs[] = { //WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //WGL_CONTEXT_MINOR_VERSION_ARB, 2, //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, theDebugCtx ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, 0, 0 }; aRendCtx = aCtx.extAll->wglCreateContextAttribsARB(hDC, NULL, aCtxAttribs); } aRendCtxTmp.nullify(); destroyWindow(hWinTmp); hRC = new StWinGlrc(hDC, aRendCtx); ST_GL_ERROR_CHECK(hRC->isValid(), STWIN_ERROR_WIN32_GLRC_CREATE, "WinAPI, Can't create GL Rendering Context"); if(theSlave != NULL) { theSlave->hRC = hRC; } ST_GL_ERROR_CHECK(hRC->makeCurrent(hDC), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Can't activate Master GL Rendering Context"); return STWIN_INIT_SUCCESS; #elif defined(__linux__) // create an OpenGL rendering context hRC = new StWinGlrc(stXDisplay, theDebugCtx); ST_GL_ERROR_CHECK(hRC->isValid(), STWIN_ERROR_X_GLRC_CREATE, "GLX, could not create rendering context for Master"); if(theSlave != NULL) { theSlave->hRC = hRC; // bind the rendering context to the window ST_GL_ERROR_CHECK(hRC->makeCurrent(theSlave->hWindowGl), STWIN_ERROR_X_GLRC_CREATE, "GLX, Can't activate Slave GL Rendering Context"); } // bind the rendering context to the window ST_GL_ERROR_CHECK(hRC->makeCurrent(hWindowGl), STWIN_ERROR_X_GLRC_CREATE, "GLX, Can't activate Master GL Rendering Context"); return STWIN_INIT_SUCCESS; #endif }
StHandle<StJpegParser::Image> StJpegParser::parseImage(const int theImgCount, const int theDepth, unsigned char* theDataStart, const bool theToFindSOI) { // check out of bounds if(theDataStart == NULL) { return StHandle<StJpegParser::Image>(); } unsigned char* aData = theDataStart; const unsigned char* aDataEnd = myBuffer + myLength; // search image beginning if(theToFindSOI) { ++aData; for(; aData < aDataEnd; ++aData) { if(aData[-1] == 0xFF && aData[0] == M_SOI) { --aData; break; } } } // check out of bounds if((aData + 2) > aDataEnd) { return StHandle<StJpegParser::Image>(); } // check the jpeg identifier if(aData[0] != 0xFF || aData[1] != M_SOI) { ST_DEBUG_LOG("StJpegParser, no SOI at position " + size_t(aData - myBuffer) + " / " + myLength); return StHandle<StJpegParser::Image>(); } aData += 2; // skip already read bytes // parse the data StHandle<StJpegParser::Image> anImg = new StJpegParser::Image(); anImg->Data = aData - 2; for(;;) { // search for the next marker in the file ++aData; // one byte forward size_t aSkippedBytes = 0; unsigned char aMarker = 0; for(; aData < aDataEnd; ++aSkippedBytes, ++aData) { aMarker = aData[0]; if(aData[-1] == 0xFF && aMarker != 0xFF && aMarker != 0x00) { ++aData; // skip marker id byte break; } } //ST_DEBUG_LOG(" #" + theImgCount + "." + theDepth + " [" + markerString(aMarker) + "] at position " + size_t(aData - myBuffer) + " / " + myLength); /// if(aMarker == M_EOI) { //ST_DEBUG_LOG("Jpeg, EOI at position " + size_t(aData - myBuffer) + " / " + myLength); anImg->Length = size_t(aData - anImg->Data); return anImg; } else if(aMarker == M_SOI) { // here the subimage (thumbnail)... //ST_DEBUG_LOG("Jpeg, SOI at position " + size_t(aData - myBuffer) + " / " + myLength); anImg->Thumb = StJpegParser::parseImage(theImgCount, theDepth + 1, aData - 2, false); if(!anImg->Thumb.isNull()) { //ST_DEBUG_LOG("anImg->Thumb->Length= " + anImg->Thumb->Length); aData += anImg->Thumb->Length - 2; } continue; } if(aData + 2 >= aDataEnd) { ST_DEBUG_LOG("Corrupt jpeg file or error in parser"); if(myImages.isNull()) { anImg->Data = myBuffer; anImg->Length = myLength; } return anImg; } else if(aSkippedBytes > 10) { //ST_DEBUG_LOG("Extraneous " + (aSkippedBytes - 1) + " padding bytes before section " + aMarker); } // read the length of the section (including these 2 bytes but excluding marker) const int anItemLen = StAlienData::Get16uBE(aData); if(anItemLen < 3 || (aData + anItemLen) > aDataEnd) { //ST_DEBUG_LOG("Invalid marker " + aMarker + " in jpeg (item lenght = " + anItemLen // + " from position " + int(aDataEnd - aData - 2) + ')'); // just ignore probably unknown sections continue; } switch(aMarker) { case M_SOF0: case M_SOF1: case M_SOF2: case M_SOF3: { if(anItemLen >= 7) { anImg->SizeY = StAlienData::Get16uBE(aData + 2 + 1); anImg->SizeX = StAlienData::Get16uBE(aData + 2 + 3); //ST_DEBUG_LOG(" SOF " + anImg->SizeX + "x" + anImg->SizeY); } aData += anItemLen; break; } case M_DRI: { if(anItemLen == 4) { //const int16_t aNbRestartBlocks = anImg->SizeY = StAlienData::Get16uBE(aData + 2); } aData += anItemLen; break; } case M_SOS: { // here the image data... //ST_DEBUG_LOG("Jpeg, SOS at position " + size_t(aData - myBuffer - 1) + " / " + myLength); aData += anItemLen; break; } case M_RST0: case M_RST1: case M_RST2: case M_RST3: case M_RST4: case M_RST5: case M_RST6: case M_RST7: { // aData += aNbRestartBlocks * aMcuSize; break; } case M_JFIF: { if(anItemLen >= 16 && stAreEqual(aData + 2, "JFIF\0", 5)) { myOffsets[Offset_Jfif] = aData - myBuffer - 2; //const int8_t aVerMaj = (int8_t )aData[7]; //const int8_t aVerMin = (int8_t )aData[8]; const JfifUnitsXY aUnits = (JfifUnitsXY )aData[9]; const uint16_t aDensityX = StAlienData::Get16uBE(aData + 10); const uint16_t aDensityY = StAlienData::Get16uBE(aData + 12); //const int8_t aThumbX = (int8_t )aData[14]; //const int8_t aThumbY = (int8_t )aData[15]; if(aUnits == JfifUnitsXY_AspectRatio) { anImg->ParX = aDensityX; anImg->ParY = aDensityY; } //ST_DEBUG_LOG(" ## JFIF" + aVerMaj + "." + aVerMin + " u" + (int )aUnits + " " + aDensityX + "x" + aDensityY // + " thumb " + aThumbX + "x" + aThumbY); } else if(stAreEqual(aData + 2, "JFXX\0", 5)) { // JFIF extension } aData += anItemLen; break; } case M_EXIF: case M_APP2: { myOffsets[aMarker == M_EXIF ? Offset_Exif : Offset_ExifExtra] = aData - myBuffer - 2; // there can be different section using the same marker if(stAreEqual(aData + 2, "Exif\0\0", 6)) { //ST_DEBUG_LOG("Exif section..."); StHandle<StExifDir> aSubDir = new StExifDir(); anImg->Exif.add(aSubDir); if(!aSubDir->parseExif(anImg->Exif, aData + 8, anItemLen - 8)) { // } } else if(stAreEqual(aData + 2, "MPF\0", 4)) { // MP Extensions (MPO) StHandle<StExifDir> aSubDir = new StExifDir(); aSubDir->Type = StExifDir::DType_MPO; anImg->Exif.add(aSubDir); if(!aSubDir->parseExif(anImg->Exif, aData + 6, anItemLen - 6)) { // } } else if(stAreEqual(aData + 2, "http:", 5)) { //ST_DEBUG_LOG("Image cotains XMP section"); } else { //ST_DEBUG_LOG(" @@@ APP2 " + StString((char* )aData + 2)); } // skip already read bytes aData += anItemLen; break; } case M_APP3: { if(anItemLen >= 16 && stAreEqual(aData + 2, "_JPSJPS_", 8)) { // outdated VRex section myOffsets[Offset_Jps] = aData - myBuffer - 2; //ST_DEBUG_LOG("Jpeg, _JPSJPS_ section (len= )" + anItemLen); //const uint16_t aBlockLen = StAlienData::Get16uBE(aData + 10); const uint32_t aStereoDesc = StAlienData::Get32uBE(aData + 12); #define SD_LAYOUT_INTERLEAVED 0x00000100 #define SD_LAYOUT_SIDEBYSIDE 0x00000200 #define SD_LAYOUT_OVERUNDER 0x00000300 #define SD_LAYOUT_ANAGLYPH 0x00000400 #define SD_HALF_HEIGHT 0x00010000 #define SD_HALF_WIDTH 0x00020000 #define SD_LEFT_FIELD_FIRST 0x00040000 if(aStereoDesc & 0x00000001) { const bool isLeftFirst = (aStereoDesc & SD_LEFT_FIELD_FIRST) != 0; switch(aStereoDesc & 0x0000FF00) { case SD_LAYOUT_INTERLEAVED: myStFormat = ST_V_SRC_ROW_INTERLACE; break; case SD_LAYOUT_SIDEBYSIDE: myStFormat = isLeftFirst ? ST_V_SRC_PARALLEL_PAIR : ST_V_SRC_SIDE_BY_SIDE; break; case SD_LAYOUT_OVERUNDER: myStFormat = isLeftFirst ? ST_V_SRC_OVER_UNDER_LR : ST_V_SRC_OVER_UNDER_RL; break; case SD_LAYOUT_ANAGLYPH: myStFormat = ST_V_SRC_ANAGLYPH_RED_CYAN; break; default: break; } } else { myStFormat = ST_V_SRC_MONO; } if(anItemLen > 18) { const uint16_t aStringLen = StAlienData::Get16uBE(aData + 16); char* aStrData = (char* )aData + 18; myJpsComment = StString(aStrData, aStringLen); } } // skip already read bytes aData += anItemLen; break; } case M_DQT: { myOffsets[Offset_Dqt] = aData - myBuffer - 2; aData += anItemLen; break; } case M_APP4: case M_APP5: case M_APP6: case M_APP7: case M_APP8: case M_APP9: case M_APP10: case M_APP11: case M_APP12: case M_APP13: case M_APP14: case M_APP15: case M_DHT: { aData += anItemLen; break; } case M_COM: { myOffsets[Offset_Comment] = aData - myBuffer - 2; if(anItemLen > 2) { myComment = StString((char* )aData + 2, anItemLen - 2); } //ST_DEBUG_LOG("StJpegParser, comment= '" + myComment + "'"); aData += anItemLen; break; } default: { // carefully skip unknown sections //aData += anItemLen; break; } } } }
bool StDXManager::getInfo(StDXInfo& theInfo, const bool theForced) { if(!theForced) { if(ST_DX_HAS_CACHED_INFO) { theInfo = ST_DX_CACHED_INFO; return true; } } const StStringUtfWide AQBS_TEST_CLASS = L"StTESTAqbsWin"; HINSTANCE anAppInst = GetModuleHandle(NULL); WNDCLASSW aWinClass; aWinClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; aWinClass.lpfnWndProc = (WNDPROC )aDummyWinProc; aWinClass.cbClsExtra = 0; aWinClass.cbWndExtra = 0; aWinClass.hInstance = anAppInst; aWinClass.hIcon = LoadIcon(anAppInst, L"A"); aWinClass.hCursor = LoadCursor(NULL, IDC_ARROW); aWinClass.hbrBackground = NULL; aWinClass.lpszMenuName = NULL; aWinClass.lpszClassName = AQBS_TEST_CLASS.toCString(); // class name if(RegisterClassW(&aWinClass) == 0) { ST_DEBUG_LOG("Failed to RegisterClass '" + AQBS_TEST_CLASS.toUtf8() + "'"); return false; } HWND aWinHandle = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, AQBS_TEST_CLASS.toCString(), L"StTESTAqbs Window", WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 32, 32, 32, 32, NULL, NULL, anAppInst, NULL); if(aWinHandle == NULL) { ST_DEBUG_LOG("Failed to create 'StTESTAqbsWin' window (" + int(GetLastError()) + ")"); UnregisterClassW(AQBS_TEST_CLASS.toCString(), anAppInst); return false; } StHandle<StDXManager> aDXManager = new StDXManager(); // test AQBS support theInfo.hasAqbsSupport = aDXManager->checkAqbsSupport(aWinHandle); // enumerate available adapters if(aDXManager->myD3dLib != NULL) { const UINT aD3dAdaptersNb = aDXManager->getAdapterCount(); D3DADAPTER_IDENTIFIER9 anAdapterInfo; for(UINT anAdapterIter = 0; anAdapterIter < aD3dAdaptersNb; ++anAdapterIter) { aDXManager->getAdapterIdentifier(anAdapterIter, 0, &anAdapterInfo); if(anAdapterInfo.VendorId == ST_DX_VENDOR_AMD) { theInfo.hasAmdAdapter = true; } else if(anAdapterInfo.VendorId == ST_DX_VENDOR_NVIDIA) { theInfo.hasNvAdapter = true; } } } // release resources aDXManager.nullify(); DestroyWindow(aWinHandle); UnregisterClass(AQBS_TEST_CLASS.toCString(), anAppInst); // check NVIDIA Stereo enabled state if(NvAPI_Initialize() == NVAPI_OK) { NvU8 isStereoEnabled = FALSE; NvAPI_Stereo_IsEnabled(&isStereoEnabled); theInfo.hasNvStereoSupport = isStereoEnabled == TRUE; } //ST_DEBUG_LOG("DXInfo, AMD(" + int(theInfo.hasAmdAdapter) + "), AQBS(" + int(theInfo.hasAqbsSupport) // + "); NVIDIA(" + int(theInfo.hasNvAdapter) + "), NvStereo(" + int(theInfo.hasNvStereoSupport) + ")"); // cache the state to avoid unnecessary calls ST_DX_CACHED_INFO = theInfo; ST_DX_HAS_CACHED_INFO = true; return true; }
IDirect3DDevice9* StDXManager::createAqbsDevice(const UINT theAdapterId, const HWND theWinHandle, const D3DPRESENT_PARAMETERS& theD3dParams) { // first create a temporary windowed device IDirect3DDevice9* aD3dDevTmp = StDXManager::createAqbsTmpDevice(theAdapterId, theWinHandle, theD3dParams); if(aD3dDevTmp == NULL) { return NULL; } // create a surface to be used to communicate with the driver StHandle<StDXAqbsControl> anAqbsControl = new StDXAqbsControl(aD3dDevTmp); if(!anAqbsControl->isValid()) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to create AQBS sufrace"); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } // send the command to the driver using the temporary surface if(!anAqbsControl->enableStereo()) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to enable stereo via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } myWithAqbs = true; // see what stereo modes are available ATIDX9GETDISPLAYMODES aDispModeParams; stMemSet(&aDispModeParams, 0, sizeof(ATIDX9GETDISPLAYMODES)); // send stereo command to get the number of available stereo modes. if(!anAqbsControl->sendCommand(ATI_STEREO_GETDISPLAYMODES, (BYTE* )&aDispModeParams, sizeof(ATIDX9GETDISPLAYMODES))) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to enumerate stereo modes via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; return NULL; } if(aDispModeParams.dwNumModes != 0) { // allocating memory to get the list of modes. aDispModeParams.pStereoModes = new D3DDISPLAYMODE[aDispModeParams.dwNumModes]; // send stereo command to get the list of stereo modes if(!anAqbsControl->sendCommand(ATI_STEREO_GETDISPLAYMODES, (BYTE* )&aDispModeParams, sizeof(ATIDX9GETDISPLAYMODES))) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), fail to retrieve stereo modes via AQBS sufrace"); anAqbsControl.nullify(); aD3dDevTmp->Release(); aD3dDevTmp = NULL; delete[] aDispModeParams.pStereoModes; return NULL; } } anAqbsControl.nullify(); int aResFormatMatch = -1; ///ST_DEBUG_LOG(" DX CUDD " + printDisplayFormat(theD3dParams)); ///ST_DEBUG_LOG(" DX CURR " + printDisplayFormat(myCurrMode)); for(int aDispModeIter = int(aDispModeParams.dwNumModes - 1); aDispModeIter >= 0; --aDispModeIter) { const D3DDISPLAYMODE& aDispMode = aDispModeParams.pStereoModes[aDispModeIter]; ///ST_DEBUG_LOG(" DX ST " + printDisplayFormat(aDispMode)); if(aDispMode.Width != theD3dParams.BackBufferWidth || aDispMode.Height != theD3dParams.BackBufferHeight || aDispMode.Format != theD3dParams.BackBufferFormat) { continue; } aResFormatMatch = aDispModeIter; break; } if(aResFormatMatch < 0) { ST_DEBUG_LOG("StDXManager::createAqbsDevice(), stereo display format doesn't found"); aD3dDevTmp->Release(); aD3dDevTmp = NULL; delete[] aDispModeParams.pStereoModes; return NULL; } int aRefreshMatch = -1; UINT aRefreshMax = 0; for(int aDispModeIter = aResFormatMatch; aDispModeIter >= 0; --aDispModeIter) { const D3DDISPLAYMODE& aDispMode = aDispModeParams.pStereoModes[aDispModeIter]; ST_DEBUG_LOG(" DX ST " + printDisplayFormat(aDispMode)); if(aDispMode.Width != theD3dParams.BackBufferWidth || aDispMode.Height != theD3dParams.BackBufferHeight || aDispMode.Format != theD3dParams.BackBufferFormat) { continue; } if(aDispMode.RefreshRate == myRefreshRate) { aRefreshMatch = aDispModeIter; // found a match with the current refresh break; } else if(aDispMode.RefreshRate > aRefreshMax) { aRefreshMax = aDispMode.RefreshRate; aRefreshMatch = aDispModeIter; } } ST_DEBUG_LOG(" DXSSS " + printDisplayFormat(aDispModeParams.pStereoModes[aRefreshMatch])); // a valid multisample value other then 0 or 1 must be set for stereo (ex 2) D3DPRESENT_PARAMETERS aD3dParams = theD3dParams; aD3dParams.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES; aD3dParams.Flags = 0; // can't lock the back buffer aD3dParams.EnableAutoDepthStencil = FALSE; // need to create a special depth buffer aD3dParams.FullScreen_RefreshRateInHz = aDispModeParams.pStereoModes[aRefreshMatch].RefreshRate; aD3dParams.BackBufferFormat = aDispModeParams.pStereoModes[aRefreshMatch].Format; myRefreshRate = aDispModeParams.pStereoModes[aRefreshMatch].RefreshRate; delete[] aDispModeParams.pStereoModes; // override original parameters myD3dParams = aD3dParams; return aD3dDevTmp; }