Cocoa Port:

- Add support for handling combination native/custom rendering sizes.
- As a side-effect of supporting this feature, pixel scalers now work as intended when high-resolution rendering is enabled (but only if the incoming display framebuffer is at the native size).
This commit is contained in:
rogerman 2015-08-25 18:56:03 +00:00
parent e8cd47acf0
commit e344486e8a
6 changed files with 272 additions and 241 deletions

View File

@ -5612,7 +5612,6 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
{ {
_output = oglVO; _output = oglVO;
_needUploadVertices = true; _needUploadVertices = true;
_needUploadTexCoords = true;
_useDeposterize = false; _useDeposterize = false;
_displayWidth = GPU_DISPLAY_WIDTH; _displayWidth = GPU_DISPLAY_WIDTH;
@ -5626,60 +5625,90 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
_normalWidth = _displayWidth; _normalWidth = _displayWidth;
_normalHeight = _displayHeight*2.0 + ((_displayHeight * DS_DISPLAY_VERTICAL_GAP_TO_HEIGHT_RATIO) * _gapScalar); _normalHeight = _displayHeight*2.0 + ((_displayHeight * DS_DISPLAY_VERTICAL_GAP_TO_HEIGHT_RATIO) * _gapScalar);
_vf[0] = new VideoFilter(_displayWidth, _displayHeight, VideoFilterTypeID_None, 0); _vf[0] = new VideoFilter(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, VideoFilterTypeID_None, 0);
_vf[1] = new VideoFilter(_displayWidth, _displayHeight, VideoFilterTypeID_None, 0); _vf[1] = new VideoFilter(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, VideoFilterTypeID_None, 0);
_vfDual = new VideoFilter(_vf[0]->GetSrcWidth(), _vf[0]->GetSrcHeight() + _vf[1]->GetSrcHeight(), VideoFilterTypeID_None, 2);
_vfMasterDstBuffer = (uint32_t *)calloc(_vfDual->GetDstWidth() * _vfDual->GetDstHeight(), sizeof(uint32_t)); _vfMasterDstBuffer = (uint32_t *)calloc(_vf[0]->GetSrcWidth() * (_vf[0]->GetSrcHeight() + _vf[1]->GetSrcHeight()), sizeof(uint32_t));
_vf[0]->SetDstBufferPtr(_vfMasterDstBuffer); _vf[0]->SetDstBufferPtr(_vfMasterDstBuffer);
_vf[1]->SetDstBufferPtr(_vfMasterDstBuffer + (_vf[0]->GetDstWidth() * _vf[0]->GetDstHeight())); _vf[1]->SetDstBufferPtr(_vfMasterDstBuffer + (_vf[0]->GetDstWidth() * _vf[0]->GetDstHeight()));
_vfDual->SetDstBufferPtr(_vfMasterDstBuffer);
_displayTexFilter[0] = GL_NEAREST; _displayTexFilter[0] = GL_NEAREST;
_displayTexFilter[1] = GL_NEAREST; _displayTexFilter[1] = GL_NEAREST;
_vtxBufferOffset = 0; _vtxBufferOffset = 0;
UpdateVertices(); UpdateVertices();
UpdateTexCoords(_vf[0]->GetDstWidth(), _vf[0]->GetDstHeight()); UpdateTexCoords(_vf[0]->GetDstWidth(), _vf[0]->GetDstHeight(), _vf[1]->GetDstWidth(), _vf[1]->GetDstHeight());
_isTexVideoInputDataNative[0] = true;
_isTexVideoInputDataNative[1] = true;
_texLoadedWidth[0] = (GLfloat)GPU_DISPLAY_WIDTH;
_texLoadedWidth[1] = (GLfloat)GPU_DISPLAY_WIDTH;
_texLoadedHeight[0] = (GLfloat)GPU_DISPLAY_HEIGHT;
_texLoadedHeight[1] = (GLfloat)GPU_DISPLAY_HEIGHT;
// Set up textures // Set up textures
glGenTextures(2, _texCPUFilterDstID); glGenTextures(2, _texCPUFilterDstID);
glGenTextures(2, _texVideoInputDataID); glGenTextures(2, _texVideoInputDataNativeID);
_texVideoSourceID[0] = _texVideoInputDataID[0]; glGenTextures(2, _texVideoInputDataCustomID);
_texVideoSourceID[1] = _texVideoInputDataID[1]; _texVideoOutputID[0] = _texVideoInputDataNativeID[0];
_texVideoPixelScalerID[0] = _texVideoInputDataID[0]; _texVideoOutputID[1] = _texVideoInputDataNativeID[1];
_texVideoPixelScalerID[1] = _texVideoInputDataID[1];
_texVideoOutputID[0] = _texVideoInputDataID[0];
_texVideoOutputID[1] = _texVideoInputDataID[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texCPUFilterDstID[0]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texCPUFilterDstID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE);
glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, _vf[0]->GetDstWidth() * _vf[0]->GetDstHeight() * sizeof(uint32_t), _vf[0]->GetDstBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, _vf[0]->GetDstWidth(), _vf[0]->GetDstHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _vf[0]->GetDstBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texCPUFilterDstID[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texCPUFilterDstID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataID[0]); glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, _vf[1]->GetDstWidth() * _vf[1]->GetDstHeight() * sizeof(uint32_t), _vf[1]->GetDstBufferPtr());
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, _vf[0]->GetSrcWidth(), _vf[0]->GetSrcHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[0]->GetSrcBufferPtr()); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, _vf[1]->GetDstWidth(), _vf[1]->GetDstHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _vf[1]->GetDstBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataID[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataNativeID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, _vf[1]->GetSrcWidth(), _vf[1]->GetSrcHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[1]->GetSrcBufferPtr()); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[0]->GetSrcBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataNativeID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[1]->GetSrcBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataCustomID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[0]->GetSrcBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texVideoInputDataCustomID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, _vf[1]->GetSrcBufferPtr());
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@ -5791,7 +5820,8 @@ OGLDisplayLayer::~OGLDisplayLayer()
glDeleteBuffersARB(1, &this->_vboTexCoordID); glDeleteBuffersARB(1, &this->_vboTexCoordID);
glDeleteBuffersARB(1, &this->_vboElementID); glDeleteBuffersARB(1, &this->_vboElementID);
glDeleteTextures(2, this->_texCPUFilterDstID); glDeleteTextures(2, this->_texCPUFilterDstID);
glDeleteTextures(2, this->_texVideoInputDataID); glDeleteTextures(2, this->_texVideoInputDataNativeID);
glDeleteTextures(2, this->_texVideoInputDataCustomID);
glActiveTexture(GL_TEXTURE0 + 1); glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_3D, 0); glBindTexture(GL_TEXTURE_3D, 0);
@ -5817,7 +5847,6 @@ OGLDisplayLayer::~OGLDisplayLayer()
delete this->_vf[0]; delete this->_vf[0];
delete this->_vf[1]; delete this->_vf[1];
delete this->_vfDual;
free(_vfMasterDstBuffer); free(_vfMasterDstBuffer);
} }
@ -5872,15 +5901,6 @@ void OGLDisplayLayer::SetFiltersPreferGPUOGL(bool preferGPU)
{ {
this->_filtersPreferGPU = preferGPU; this->_filtersPreferGPU = preferGPU;
this->_useShaderBasedPixelScaler = (preferGPU) ? this->SetGPUPixelScalerOGL(this->_pixelScaler) : false; this->_useShaderBasedPixelScaler = (preferGPU) ? this->SetGPUPixelScalerOGL(this->_pixelScaler) : false;
if (this->_useShaderBasedPixelScaler)
{
this->UpdateTexCoords(this->_shaderFilter[0]->GetDstWidth(), this->_shaderFilter[0]->GetDstHeight());
}
else
{
this->UpdateTexCoords(this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight());
}
} }
uint16_t OGLDisplayLayer::GetDisplayWidth() uint16_t OGLDisplayLayer::GetDisplayWidth()
@ -5899,41 +5919,21 @@ void OGLDisplayLayer::SetDisplaySize(uint16_t w, uint16_t h)
this->_displayHeight = h; this->_displayHeight = h;
this->GetNormalSize(this->_normalWidth, this->_normalHeight); this->GetNormalSize(this->_normalWidth, this->_normalHeight);
const VideoFilterAttributes filterAttr = this->_vf[0]->GetAttributes(); uint32_t *emptyBuffer = (uint32_t *)calloc(w * h, sizeof(uint32_t));
this->ResizeCPUPixelScalerOGL(w, h, w, h, filterAttr.scaleMultiply, filterAttr.scaleDivide);
this->_vf[0]->SetSourceSize(w, h);
this->_vf[1]->SetSourceSize(w, h);
this->_vfDual->SetSourceSize(w, this->_vf[0]->GetSrcHeight() + this->_vf[1]->GetSrcHeight());
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[0]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_vf[0]->GetSrcWidth(), this->_vf[0]->GetSrcHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_vf[0]->GetSrcBufferPtr()); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, emptyBuffer);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_vf[1]->GetSrcWidth(), this->_vf[1]->GetSrcHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_vf[1]->GetSrcBufferPtr()); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, emptyBuffer);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
if (this->_canUseShaderBasedFilters) free(emptyBuffer);
{
for (size_t i = 0; i < 2; i++)
{
this->_filterDeposterize[i]->SetSrcSizeOGL(this->_vf[i]->GetSrcWidth(), this->_vf[i]->GetSrcHeight());
this->_shaderFilter[i]->SetSrcSizeOGL(this->_vf[i]->GetSrcWidth(), this->_vf[i]->GetSrcHeight());
}
}
if (this->_useShaderBasedPixelScaler)
{
this->UpdateTexCoords(this->_shaderFilter[0]->GetDstWidth(), this->_shaderFilter[0]->GetDstHeight());
}
else
{
this->UpdateTexCoords(this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight());
}
this->UpdateVertices(); this->UpdateVertices();
} }
@ -6067,16 +6067,17 @@ void OGLDisplayLayer::UpdateVertices()
this->_needUploadVertices = true; this->_needUploadVertices = true;
} }
void OGLDisplayLayer::UpdateTexCoords(GLfloat s, GLfloat t) void OGLDisplayLayer::UpdateTexCoords(GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1)
{ {
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f; texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f; texCoordBuffer[2] = s0; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t; texCoordBuffer[4] = s0; texCoordBuffer[5] = t0;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t; texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t0;
memcpy(texCoordBuffer + (1 * 8), texCoordBuffer + (0 * 8), sizeof(GLint) * (1 * 8)); texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = 0.0f;
texCoordBuffer[10] = s1; texCoordBuffer[11] = 0.0f;
this->_needUploadTexCoords = true; texCoordBuffer[12] = s1; texCoordBuffer[13] = t1;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t1;
} }
bool OGLDisplayLayer::CanUseShaderBasedFilters() bool OGLDisplayLayer::CanUseShaderBasedFilters()
@ -6112,7 +6113,6 @@ void OGLDisplayLayer::ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const s
uint32_t *newMasterBuffer = (uint32_t *)calloc(newDstBufferWidth * newDstBufferHeight, sizeof(uint32_t)); uint32_t *newMasterBuffer = (uint32_t *)calloc(newDstBufferWidth * newDstBufferHeight, sizeof(uint32_t));
this->_vf[0]->SetDstBufferPtr(newMasterBuffer); this->_vf[0]->SetDstBufferPtr(newMasterBuffer);
this->_vf[1]->SetDstBufferPtr(newMasterBuffer + ((srcWidthMain * scaleMultiply / scaleDivide) * (srcHeightMain * scaleMultiply / scaleDivide)) ); this->_vf[1]->SetDstBufferPtr(newMasterBuffer + ((srcWidthMain * scaleMultiply / scaleDivide) * (srcHeightMain * scaleMultiply / scaleDivide)) );
this->_vfDual->SetDstBufferPtr(newMasterBuffer);
const GLsizei newDstBufferSingleWidth = srcWidthMain * scaleMultiply / scaleDivide; const GLsizei newDstBufferSingleWidth = srcWidthMain * scaleMultiply / scaleDivide;
const GLsizei newDstBufferSingleHeight = srcHeightMain * scaleMultiply / scaleDivide; const GLsizei newDstBufferSingleHeight = srcHeightMain * scaleMultiply / scaleDivide;
@ -6150,7 +6150,6 @@ void OGLDisplayLayer::UploadTexCoordsOGL()
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID); glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLfloat) * (2 * 8), this->texCoordBuffer); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLfloat) * (2 * 8), this->texCoordBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
this->_needUploadTexCoords = false;
} }
void OGLDisplayLayer::UploadTransformationOGL() void OGLDisplayLayer::UploadTransformationOGL()
@ -6270,15 +6269,6 @@ void OGLDisplayLayer::SetPixelScalerOGL(const int filterID)
this->SetCPUPixelScalerOGL(newFilterID); this->SetCPUPixelScalerOGL(newFilterID);
this->_useShaderBasedPixelScaler = (this->GetFiltersPreferGPU()) ? this->SetGPUPixelScalerOGL(newFilterID) : false; this->_useShaderBasedPixelScaler = (this->GetFiltersPreferGPU()) ? this->SetGPUPixelScalerOGL(newFilterID) : false;
this->_pixelScaler = newFilterID; this->_pixelScaler = newFilterID;
if (this->_useShaderBasedPixelScaler)
{
this->UpdateTexCoords(this->_shaderFilter[0]->GetDstWidth(), this->_shaderFilter[0]->GetDstHeight());
}
else
{
this->UpdateTexCoords(this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight());
}
} }
bool OGLDisplayLayer::SetGPUPixelScalerOGL(const VideoFilterTypeID filterID) bool OGLDisplayLayer::SetGPUPixelScalerOGL(const VideoFilterTypeID filterID)
@ -6568,41 +6558,83 @@ void OGLDisplayLayer::SetCPUPixelScalerOGL(const VideoFilterTypeID filterID)
this->_vf[0]->ChangeFilterByID(filterID); this->_vf[0]->ChangeFilterByID(filterID);
this->_vf[1]->ChangeFilterByID(filterID); this->_vf[1]->ChangeFilterByID(filterID);
this->_vfDual->ChangeFilterByID(filterID);
} }
void OGLDisplayLayer::LoadFrameOGL(const uint16_t *frameData, GLint x, GLint y, GLsizei w, GLsizei h) void OGLDisplayLayer::LoadFrameOGL(const uint16_t *frameData0, const uint16_t *frameData1, GLsizei w0, GLsizei h0, GLsizei w1, GLsizei h1)
{ {
const bool isUsingCPUPixelScaler = this->_pixelScaler != VideoFilterTypeID_None && !this->_useShaderBasedPixelScaler; const bool isUsingCPUPixelScaler = this->_pixelScaler != VideoFilterTypeID_None && !this->_useShaderBasedPixelScaler;
bool loadDualScreen = (y == 0) && (h > this->_displayHeight); const bool loadMainScreen = (frameData0 != NULL);
bool loadSingleMainScreen = (y == 0); const bool loadTouchScreen = (frameData1 != NULL);
bool loadSingleTouchScreen = (y > 0);
if (!isUsingCPUPixelScaler || this->_useDeposterize) this->_isTexVideoInputDataNative[0] = ( (w0 == GPU_DISPLAY_WIDTH) && (h0 == GPU_DISPLAY_HEIGHT) );
this->_isTexVideoInputDataNative[1] = ( (w1 == GPU_DISPLAY_WIDTH) && (h1 == GPU_DISPLAY_HEIGHT) );
this->_texLoadedWidth[0] = (GLfloat)w0;
this->_texLoadedHeight[0] = (GLfloat)h0;
this->_texLoadedWidth[1] = (GLfloat)w1;
this->_texLoadedHeight[1] = (GLfloat)h1;
if (loadMainScreen)
{ {
if (loadDualScreen) if (this->_useDeposterize && this->_canUseShaderBasedFilters)
{ {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[0]); if ( (this->_filterDeposterize[0]->GetSrcWidth() != w0) || (this->_filterDeposterize[0]->GetSrcHeight() != h0) )
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w, h/2, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData); {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[1]); this->_filterDeposterize[0]->SetSrcSizeOGL(w0, h0);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w, h/2, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData + (w * (h/2))); }
}
else if (loadSingleMainScreen)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData);
}
else if (loadSingleTouchScreen)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData + (w * h));
} }
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); if (this->_isTexVideoInputDataNative[0])
{
if (!isUsingCPUPixelScaler || this->_useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w0, h0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
else
{
RGB555ToBGRA8888Buffer(frameData0, this->_vf[0]->GetSrcBufferPtr(), w0 * h0);
}
}
else
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w0, h0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
} }
else
if (loadTouchScreen)
{ {
RGB555ToBGRA8888Buffer(frameData, (loadDualScreen) ? this->_vfDual->GetSrcBufferPtr() : this->_vf[(loadSingleMainScreen) ? 0 : 1]->GetSrcBufferPtr(), w * h); if (this->_useDeposterize && this->_canUseShaderBasedFilters)
{
if ( (this->_filterDeposterize[1]->GetSrcWidth() != w1) || (this->_filterDeposterize[1]->GetSrcHeight() != h1) )
{
this->_filterDeposterize[1]->SetSrcSizeOGL(w1, h1);
}
}
if (this->_isTexVideoInputDataNative[1])
{
if (!isUsingCPUPixelScaler || this->_useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w1, h1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData1);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
else
{
RGB555ToBGRA8888Buffer(frameData1, this->_vf[1]->GetSrcBufferPtr(), w1 * h1);
}
}
else
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w1, h1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frameData1);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
} }
} }
@ -6612,101 +6644,93 @@ void OGLDisplayLayer::ProcessOGL()
const int displayMode = this->GetMode(); const int displayMode = this->GetMode();
// Source // Source
GLuint texVideoSourceID[2] = { (this->_isTexVideoInputDataNative[0]) ? this->_texVideoInputDataNativeID[0] : this->_texVideoInputDataCustomID[0],
(this->_isTexVideoInputDataNative[1]) ? this->_texVideoInputDataNativeID[1] : this->_texVideoInputDataCustomID[1] };
if (this->_useDeposterize) if (this->_useDeposterize)
{ {
this->_texVideoSourceID[0] = this->_filterDeposterize[0]->RunFilterOGL(this->_texVideoInputDataID[0]); texVideoSourceID[0] = this->_filterDeposterize[0]->RunFilterOGL(texVideoSourceID[0]);
this->_texVideoSourceID[1] = this->_filterDeposterize[1]->RunFilterOGL(this->_texVideoInputDataID[1]); texVideoSourceID[1] = this->_filterDeposterize[1]->RunFilterOGL(texVideoSourceID[1]);
if (isUsingCPUPixelScaler) // Hybrid CPU/GPU-based path (may cause a performance hit on pixel download) if (isUsingCPUPixelScaler) // Hybrid CPU/GPU-based path (may cause a performance hit on pixel download)
{ {
switch (displayMode) if ( this->_isTexVideoInputDataNative[0] && ((displayMode == DS_DISPLAY_TYPE_MAIN) || (displayMode == DS_DISPLAY_TYPE_DUAL)) )
{ {
case DS_DISPLAY_TYPE_MAIN: this->_filterDeposterize[0]->DownloadDstBufferOGL(this->_vf[0]->GetSrcBufferPtr(), 0, this->_filterDeposterize[0]->GetSrcHeight());
this->_filterDeposterize[0]->DownloadDstBufferOGL(this->_vf[0]->GetSrcBufferPtr(), 0, this->_filterDeposterize[0]->GetSrcHeight()); }
break;
if ( this->_isTexVideoInputDataNative[1] && ((displayMode == DS_DISPLAY_TYPE_TOUCH) || (displayMode == DS_DISPLAY_TYPE_DUAL)) )
case DS_DISPLAY_TYPE_TOUCH: {
this->_filterDeposterize[1]->DownloadDstBufferOGL(this->_vf[1]->GetSrcBufferPtr(), 0, this->_filterDeposterize[1]->GetSrcHeight()); this->_filterDeposterize[1]->DownloadDstBufferOGL(this->_vf[1]->GetSrcBufferPtr(), 0, this->_filterDeposterize[1]->GetSrcHeight());
break;
case DS_DISPLAY_TYPE_DUAL:
this->_filterDeposterize[0]->DownloadDstBufferOGL(this->_vfDual->GetSrcBufferPtr(), 0, this->_filterDeposterize[0]->GetSrcHeight());
this->_filterDeposterize[1]->DownloadDstBufferOGL(this->_vfDual->GetSrcBufferPtr() + (this->_vf[0]->GetSrcWidth() * this->_vf[0]->GetSrcHeight()), 0, this->_filterDeposterize[1]->GetSrcHeight());
break;
default:
break;
} }
} }
} }
else
{
this->_texVideoSourceID[0] = this->_texVideoInputDataID[0];
this->_texVideoSourceID[1] = this->_texVideoInputDataID[1];
}
// Pixel scaler // Pixel scaler - only perform on native resolution video input
if (!isUsingCPUPixelScaler) GLuint texVideoPixelScalerID[2] = { texVideoSourceID[0], texVideoSourceID[1] };
GLfloat w0 = this->_texLoadedWidth[0];
GLfloat h0 = this->_texLoadedHeight[0];
GLfloat w1 = this->_texLoadedWidth[1];
GLfloat h1 = this->_texLoadedHeight[1];
if (this->_isTexVideoInputDataNative[0])
{ {
if (this->_useShaderBasedPixelScaler) if (!isUsingCPUPixelScaler)
{ {
this->_texVideoPixelScalerID[0] = this->_shaderFilter[0]->RunFilterOGL(this->_texVideoSourceID[0]); if (this->_useShaderBasedPixelScaler)
this->_texVideoPixelScalerID[1] = this->_shaderFilter[1]->RunFilterOGL(this->_texVideoSourceID[1]); {
texVideoPixelScalerID[0] = this->_shaderFilter[0]->RunFilterOGL(texVideoSourceID[0]);
w0 = this->_shaderFilter[0]->GetDstWidth();
h0 = this->_shaderFilter[0]->GetDstHeight();
}
} }
else else
{ {
this->_texVideoPixelScalerID[0] = this->_texVideoSourceID[0]; if (displayMode == DS_DISPLAY_TYPE_MAIN || displayMode == DS_DISPLAY_TYPE_DUAL)
this->_texVideoPixelScalerID[1] = this->_texVideoSourceID[1];
}
}
else
{
switch (displayMode)
{
case DS_DISPLAY_TYPE_MAIN:
{ {
uint32_t *texData = this->_vf[0]->RunFilter(); uint32_t *texData = this->_vf[0]->RunFilter();
this->_texVideoPixelScalerID[0] = this->_texCPUFilterDstID[0]; texVideoPixelScalerID[0] = this->_texCPUFilterDstID[0];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoPixelScalerID[0]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texVideoPixelScalerID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData); glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
break;
}
case DS_DISPLAY_TYPE_TOUCH: w0 = this->_vf[0]->GetDstWidth();
h0 = this->_vf[0]->GetDstHeight();
}
}
}
if (this->_isTexVideoInputDataNative[1])
{
if (!isUsingCPUPixelScaler)
{
if (this->_useShaderBasedPixelScaler)
{
texVideoPixelScalerID[1] = this->_shaderFilter[1]->RunFilterOGL(texVideoSourceID[1]);
w1 = this->_shaderFilter[1]->GetDstWidth();
h1 = this->_shaderFilter[1]->GetDstHeight();
}
}
else
{
if (displayMode == DS_DISPLAY_TYPE_TOUCH || displayMode == DS_DISPLAY_TYPE_DUAL)
{ {
uint32_t *texData = this->_vf[1]->RunFilter(); uint32_t *texData = this->_vf[1]->RunFilter();
this->_texVideoPixelScalerID[1] = this->_texCPUFilterDstID[1]; texVideoPixelScalerID[1] = this->_texCPUFilterDstID[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoPixelScalerID[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texVideoPixelScalerID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[1]->GetDstWidth(), this->_vf[1]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData); glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[1]->GetDstWidth(), this->_vf[1]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
break;
}
case DS_DISPLAY_TYPE_DUAL: w1 = this->_vf[1]->GetDstWidth();
{ h1 = this->_vf[1]->GetDstHeight();
uint32_t *texData = this->_vfDual->RunFilter();
this->_texVideoPixelScalerID[0] = this->_texCPUFilterDstID[0];
this->_texVideoPixelScalerID[1] = this->_texCPUFilterDstID[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoPixelScalerID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoPixelScalerID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[1]->GetDstWidth(), this->_vf[1]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData + (this->_vf[0]->GetDstWidth() * this->_vf[0]->GetDstHeight()));
break;
} }
default:
break;
} }
} }
// Output // Output
this->_texVideoOutputID[0] = this->_texVideoPixelScalerID[0]; this->_texVideoOutputID[0] = texVideoPixelScalerID[0];
this->_texVideoOutputID[1] = this->_texVideoPixelScalerID[1]; this->_texVideoOutputID[1] = texVideoPixelScalerID[1];
if (this->_needUploadTexCoords) this->UpdateTexCoords(w0, h0, w1, h1);
{ this->UploadTexCoordsOGL();
this->UploadTexCoordsOGL();
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
} }

View File

@ -289,7 +289,6 @@ protected:
ShaderSupportTier _shaderSupport; ShaderSupportTier _shaderSupport;
bool _needUploadVertices; bool _needUploadVertices;
bool _needUploadTexCoords;
bool _useDeposterize; bool _useDeposterize;
bool _useShaderBasedPixelScaler; bool _useShaderBasedPixelScaler;
bool _filtersPreferGPU; bool _filtersPreferGPU;
@ -301,14 +300,15 @@ protected:
OGLFilter *_shaderFilter[2]; OGLFilter *_shaderFilter[2];
GLint _displayTexFilter[2]; GLint _displayTexFilter[2];
GLuint _texVideoInputDataID[2]; bool _isTexVideoInputDataNative[2];
GLuint _texVideoSourceID[2]; GLuint _texVideoInputDataNativeID[2];
GLuint _texVideoPixelScalerID[2]; GLuint _texVideoInputDataCustomID[2];
GLuint _texVideoOutputID[2]; GLuint _texVideoOutputID[2];
GLfloat _texLoadedWidth[2];
GLfloat _texLoadedHeight[2];
uint32_t *_vfMasterDstBuffer; uint32_t *_vfMasterDstBuffer;
VideoFilter *_vf[2]; VideoFilter *_vf[2];
VideoFilter *_vfDual;
GLuint _texCPUFilterDstID[2]; GLuint _texCPUFilterDstID[2];
uint16_t _displayWidth; uint16_t _displayWidth;
@ -347,7 +347,7 @@ protected:
virtual void UploadTransformationOGL(); virtual void UploadTransformationOGL();
void UpdateVertices(); void UpdateVertices();
void UpdateTexCoords(GLfloat s, GLfloat t); void UpdateTexCoords(GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
public: public:
OGLDisplayLayer() {}; OGLDisplayLayer() {};
@ -382,7 +382,7 @@ public:
virtual void SetPixelScalerOGL(const int filterID); virtual void SetPixelScalerOGL(const int filterID);
virtual bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID); virtual bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
virtual void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID); virtual void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
virtual void LoadFrameOGL(const uint16_t *frameData, GLint x, GLint y, GLsizei w, GLsizei h); virtual void LoadFrameOGL(const uint16_t *frameData0, const uint16_t *frameData1, GLsizei w0, GLsizei h0, GLsizei w1, GLsizei h1);
virtual void ProcessOGL(); virtual void ProcessOGL();
virtual void RenderOGL(); virtual void RenderOGL();
}; };

View File

@ -104,6 +104,7 @@ GPU3DInterface *core3DList[] = {
&OSXOpenGLRendererEnd, &OSXOpenGLRendererEnd,
&OSXOpenGLRendererFramebufferDidResize); &OSXOpenGLRendererFramebufferDidResize);
GPU_SetWillAutoBlitNativeToCustomBuffer(false);
GPU_FillScreenWithBGRA5551(0x8000); GPU_FillScreenWithBGRA5551(0x8000);
return self; return self;
@ -856,20 +857,34 @@ bool GetGPUDisplayState(const GPUType gpuType)
void GPU_FillScreenWithBGRA5551(const uint16_t colorValue) void GPU_FillScreenWithBGRA5551(const uint16_t colorValue)
{ {
const size_t pixCount = GPU_GetFramebufferWidth() * GPU_GetFramebufferHeight() * 2; const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo();
const size_t pixCountNative = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT;
const size_t pixCountCustom = dispInfo.customWidth * dispInfo.customHeight;
#ifdef __APPLE__ #ifdef __APPLE__
if (pixCount % 16 == 0) const uint16_t colorValuePattern[] = {colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue};
memset_pattern16(MainScreen.gpu->nativeBuffer, colorValuePattern, pixCountNative * sizeof(uint16_t));
memset_pattern16(SubScreen.gpu->nativeBuffer, colorValuePattern, pixCountNative * sizeof(uint16_t));
if (pixCountCustom % 16 == 0)
{ {
const uint16_t colorValuePattern[] = {colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue}; memset_pattern16(MainScreen.gpu->customBuffer, colorValuePattern, pixCountCustom * sizeof(uint16_t));
memset_pattern16(GPU_screen, colorValuePattern, pixCount * sizeof(uint16_t)); memset_pattern16(SubScreen.gpu->customBuffer, colorValuePattern, pixCountCustom * sizeof(uint16_t));
} }
else else
#endif #endif
{ {
for (size_t i = 0; i < pixCount; i++) for (size_t i = 0; i < pixCountNative; i++)
{ {
GPU_screen[i] = colorValue; MainScreen.gpu->nativeBuffer[i] = colorValue;
SubScreen.gpu->nativeBuffer[i] = colorValue;
}
for (size_t i = 0; i < pixCountCustom; i++)
{
MainScreen.gpu->customBuffer[i] = colorValue;
SubScreen.gpu->customBuffer[i] = colorValue;
} }
} }
} }

View File

@ -34,14 +34,6 @@ typedef struct
double translationZ; double translationZ;
} DisplayOutputTransformData; } DisplayOutputTransformData;
typedef struct
{
uint16_t *buffer; // Pointer to frame buffer
int32_t displayModeID; // The selected display to read from
uint16_t width; // Measured in pixels
uint16_t height; // Measured in pixels
} GPUFrame;
@interface CocoaDSOutput : CocoaDSThread @interface CocoaDSOutput : CocoaDSThread
{ {
BOOL isStateChanged; BOOL isStateChanged;
@ -126,7 +118,13 @@ typedef struct
@required @required
- (void) doInitVideoOutput:(NSDictionary *)properties; - (void) doInitVideoOutput:(NSDictionary *)properties;
- (void) doLoadVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)frameDisplayMode width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight; - (void) doLoadVideoFrameUsingMode:(const NSInteger)displayMode
displayBuffer0:(const void *)buffer0
displayBuffer1:(const void *)buffer1
width0:(const NSInteger)w0
height0:(const NSInteger)h0
width1:(const NSInteger)w1
height1:(const NSInteger)h1;
- (void) doProcessVideoFrame; - (void) doProcessVideoFrame;
@optional @optional
@ -145,7 +143,6 @@ typedef struct
id <CocoaDSDisplayDelegate> delegate; id <CocoaDSDisplayDelegate> delegate;
NSSize displaySize; NSSize displaySize;
NSInteger displayMode; NSInteger displayMode;
GPUFrame _gpuFrame;
size_t _gpuCurrentWidth; size_t _gpuCurrentWidth;
size_t _gpuCurrentHeight; size_t _gpuCurrentHeight;

View File

@ -519,12 +519,6 @@
delegate = nil; delegate = nil;
displayMode = DS_DISPLAY_TYPE_DUAL; displayMode = DS_DISPLAY_TYPE_DUAL;
_gpuFrame.buffer = (uint16_t *)GPU_screen;
_gpuFrame.displayModeID = DS_DISPLAY_TYPE_DUAL;
_gpuFrame.width = GPU_DISPLAY_WIDTH;
_gpuFrame.height = GPU_DISPLAY_HEIGHT * 2;
_gpuCurrentWidth = GPU_DISPLAY_WIDTH; _gpuCurrentWidth = GPU_DISPLAY_WIDTH;
_gpuCurrentHeight = GPU_DISPLAY_HEIGHT; _gpuCurrentHeight = GPU_DISPLAY_HEIGHT;
@ -614,34 +608,6 @@
} }
} }
- (void) handleEmuFrameProcessed
{
pthread_rwlock_rdlock(self.rwlockProducer);
const uint16_t newGpuWidth = GPU_GetFramebufferWidth();
const uint16_t newGpuHeight = GPU_GetFramebufferHeight();
_gpuFrame.buffer = (uint16_t *)GPU_screen;
_gpuFrame.displayModeID = [self displayMode];
_gpuFrame.width = newGpuWidth;
_gpuFrame.height = (_gpuFrame.displayModeID == DS_DISPLAY_TYPE_DUAL) ? newGpuHeight * 2 : newGpuHeight;
pthread_rwlock_unlock(self.rwlockProducer);
if (newGpuWidth != _gpuCurrentWidth || newGpuHeight != _gpuCurrentHeight)
{
if (delegate != nil && [delegate respondsToSelector:@selector(doDisplaySizeChanged:)])
{
[(id<CocoaDSDisplayDelegate>)delegate doDisplaySizeChanged:NSMakeSize(newGpuWidth, newGpuHeight)];
}
_gpuCurrentWidth = newGpuWidth;
_gpuCurrentHeight = newGpuHeight;
}
[super handleEmuFrameProcessed];
}
- (void) handleChangeDisplayMode:(NSData *)displayModeData - (void) handleChangeDisplayMode:(NSData *)displayModeData
{ {
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayModeChanged:)]) if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayModeChanged:)])
@ -710,14 +676,13 @@
- (NSBitmapImageRep *) bitmapImageRep - (NSBitmapImageRep *) bitmapImageRep
{ {
if (_gpuFrame.buffer == NULL) const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo();
{ const NSInteger dispMode = [self displayMode];
return nil;
} uint16_t *displayBuffer = dispInfo.masterCustomBuffer;
NSUInteger w = (NSUInteger)dispInfo.customWidth;
NSUInteger h = (dispMode == DS_DISPLAY_TYPE_DUAL) ? (NSUInteger)(dispInfo.customHeight * 2) : (NSUInteger)dispInfo.customHeight;
NSSize srcSize = [self displaySize];
NSUInteger w = (NSUInteger)srcSize.width;
NSUInteger h = (NSUInteger)srcSize.height;
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:w pixelsWide:w
pixelsHigh:h pixelsHigh:h
@ -736,7 +701,9 @@
uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData]; uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData];
pthread_rwlock_rdlock(self.rwlockProducer); pthread_rwlock_rdlock(self.rwlockProducer);
RGB555ToRGBA8888Buffer((const uint16_t *)_gpuFrame.buffer, bitmapData, (w * h)); MainScreen.gpu->BlitNativeToCustomFramebuffer();
SubScreen.gpu->BlitNativeToCustomFramebuffer();
RGB555ToRGBA8888Buffer(displayBuffer, bitmapData, (w * h));
pthread_rwlock_unlock(self.rwlockProducer); pthread_rwlock_unlock(self.rwlockProducer);
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
@ -828,10 +795,34 @@
[super handleEmuFrameProcessed]; [super handleEmuFrameProcessed];
pthread_rwlock_rdlock(self.rwlockProducer); pthread_rwlock_rdlock(self.rwlockProducer);
[(id<CocoaDSDisplayVideoDelegate>)delegate doLoadVideoFrame:_gpuFrame.buffer
displayMode:_gpuFrame.displayModeID const NDSDisplayInfo &dispInfo = NDS_GetDisplayInfo();
width:_gpuFrame.width const NSInteger dispMode = [self displayMode];
height:_gpuFrame.height]; const uint16_t newGpuWidth = dispInfo.customWidth;
const uint16_t newGpuHeight = dispInfo.customHeight;
if (newGpuWidth != _gpuCurrentWidth || newGpuHeight != _gpuCurrentHeight)
{
if (delegate != nil && [delegate respondsToSelector:@selector(doDisplaySizeChanged:)])
{
[(id<CocoaDSDisplayDelegate>)delegate doDisplaySizeChanged:NSMakeSize(newGpuWidth, newGpuHeight)];
}
_gpuCurrentWidth = newGpuWidth;
_gpuCurrentHeight = newGpuHeight;
}
void *mainFramebuffer = (dispMode == DS_DISPLAY_TYPE_MAIN || dispMode == DS_DISPLAY_TYPE_DUAL) ? dispInfo.renderedBuffer[NDSDisplayID_Main] : NULL;
void *touchFramebuffer = (dispMode == DS_DISPLAY_TYPE_TOUCH || dispMode == DS_DISPLAY_TYPE_DUAL) ? dispInfo.renderedBuffer[NDSDisplayID_Touch] : NULL;
[(id<CocoaDSDisplayVideoDelegate>)delegate doLoadVideoFrameUsingMode:dispMode
displayBuffer0:mainFramebuffer
displayBuffer1:touchFramebuffer
width0:dispInfo.renderedWidth[NDSDisplayID_Main]
height0:dispInfo.renderedHeight[NDSDisplayID_Main]
width1:dispInfo.renderedWidth[NDSDisplayID_Touch]
height1:dispInfo.renderedHeight[NDSDisplayID_Touch]];
pthread_rwlock_unlock(self.rwlockProducer); pthread_rwlock_unlock(self.rwlockProducer);
[(id<CocoaDSDisplayVideoDelegate>)delegate doProcessVideoFrame]; [(id<CocoaDSDisplayVideoDelegate>)delegate doProcessVideoFrame];

View File

@ -1803,13 +1803,17 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
// No init needed, so do nothing. // No init needed, so do nothing.
} }
- (void)doLoadVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)frameDisplayMode width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight - (void) doLoadVideoFrameUsingMode:(const NSInteger)displayMode
displayBuffer0:(const void *)buffer0
displayBuffer1:(const void *)buffer1
width0:(const NSInteger)w0
height0:(const NSInteger)h0
width1:(const NSInteger)w1
height1:(const NSInteger)h1
{ {
const GLint lineOffset = (frameDisplayMode == DS_DISPLAY_TYPE_TOUCH) ? frameHeight : 0;
CGLLockContext(cglDisplayContext); CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext); CGLSetCurrentContext(cglDisplayContext);
oglv->GetDisplayLayer()->LoadFrameOGL((uint16_t *)videoFrameData, 0, lineOffset, frameWidth, frameHeight); oglv->GetDisplayLayer()->LoadFrameOGL((const uint16_t *)buffer0, (const uint16_t *)buffer1, w0, h0, w1, h1);
CGLUnlockContext(cglDisplayContext); CGLUnlockContext(cglDisplayContext);
} }