| 1007 | } |
| 1008 | |
| 1009 | bool Tr2DxtCompressSurfaceAsync( Tr2DxtCompressionFormat eCompressFmt, |
| 1010 | const unsigned char* inBuf, |
| 1011 | unsigned width, |
| 1012 | unsigned height, |
| 1013 | unsigned char* outBuf, |
| 1014 | size_t outputPitch, |
| 1015 | Tr2DxtCompressControl* control, |
| 1016 | int squishQuality ) |
| 1017 | { |
| 1018 | #if BLUE_WITH_PYTHON |
| 1019 | if( !PyOS->CanYield() ) |
| 1020 | { |
| 1021 | //this is a tasklet that cannot block |
| 1022 | PyErr_SetString( PyExc_RuntimeError, "Tr2DxtCompressSurfaceAsync: This tasklet cannot block" ); |
| 1023 | return false; |
| 1024 | } |
| 1025 | #endif |
| 1026 | |
| 1027 | if( !s_wodBackgroundCompressor ) |
| 1028 | { |
| 1029 | // Create the background welder the first time we need to build |
| 1030 | s_wodBackgroundCompressor = BeCallbackMan; |
| 1031 | } |
| 1032 | |
| 1033 | Tr2DxtCompressSurfaceAsyncData* data = CCP_NEW( "Tr2DxtCompressSurfaceAsync/data" ) Tr2DxtCompressSurfaceAsyncData; |
| 1034 | data->control = control; |
| 1035 | data->eCompressFmt = eCompressFmt; |
| 1036 | data->inBuf = inBuf; |
| 1037 | data->outBuf = outBuf; |
| 1038 | data->width = width; |
| 1039 | data->height = height; |
| 1040 | data->outputPitch = outputPitch; |
| 1041 | data->squishQuality = squishQuality; |
| 1042 | |
| 1043 | s_wodBackgroundCompressor->Add( Tr2DxtCompressSurfaceAsyncHelper, (void*)data, 0, &data->control->m_id ); |
| 1044 | |
| 1045 | while( !data->control->IsDone() ) |
| 1046 | { |
| 1047 | #if BLUE_WITH_PYTHON |
| 1048 | if( !PyOS->Yield() ) |
| 1049 | { |
| 1050 | // This is 'normal', it happens when yielding a tasklet that has already been |
| 1051 | // killed. Shouldn't be converting this into a runtime error, dixit Kristjan. |
| 1052 | // Ideally we'd want to catch the exception here and check it really is a PyExc_TaskletExit, |
| 1053 | // however by the time Yield returns it's already logged through the global _ExceptionHandler |
| 1054 | // in uicore.py |
| 1055 | data->control->Cancel(); |
| 1056 | s_wodBackgroundCompressor->Cancel( data->control->m_id ); |
| 1057 | break; |
| 1058 | } |
| 1059 | #endif |
| 1060 | } |
| 1061 | |
| 1062 | const bool result = data->succeeded; |
| 1063 | |
| 1064 | CCP_DELETE data; |
| 1065 | |
| 1066 | return result; |