| 
									
										
										
										
											2015-05-24 06:32:32 +02:00
										 |  |  | // Copyright 2010 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2+
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #include "VideoCommon/FramebufferManagerBase.h"
 | 
					
						
							| 
									
										
										
										
											2017-02-03 12:31:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 16:54:40 -04:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2015-12-21 14:11:01 -05:00
										 |  |  | #include <array>
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2017-02-03 12:31:20 -05:00
										 |  |  | #include <tuple>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoCommon/RenderBase.h"
 | 
					
						
							|  |  |  | #include "VideoCommon/VideoConfig.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-22 18:47:20 -05:00
										 |  |  | std::unique_ptr<FramebufferManagerBase> g_framebuffer_manager; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | std::unique_ptr<XFBSourceBase> | 
					
						
							|  |  |  |     FramebufferManagerBase::m_realXFBSource;  // Only used in Real XFB mode
 | 
					
						
							|  |  |  | FramebufferManagerBase::VirtualXFBListType | 
					
						
							|  |  |  |     FramebufferManagerBase::m_virtualXFBList;  // Only used in Virtual XFB mode
 | 
					
						
							|  |  |  | std::array<const XFBSourceBase*, FramebufferManagerBase::MAX_VIRTUAL_XFB> | 
					
						
							|  |  |  |     FramebufferManagerBase::m_overlappingXFBArray; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:11:15 +02:00
										 |  |  | unsigned int FramebufferManagerBase::s_last_xfb_width = 1; | 
					
						
							|  |  |  | unsigned int FramebufferManagerBase::s_last_xfb_height = 1; | 
					
						
							| 
									
										
										
										
											2012-09-28 23:48:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 11:41:39 +01:00
										 |  |  | unsigned int FramebufferManagerBase::m_EFBLayers = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | FramebufferManagerBase::FramebufferManagerBase() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Can't hurt
 | 
					
						
							|  |  |  |   m_overlappingXFBArray.fill(nullptr); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FramebufferManagerBase::~FramebufferManagerBase() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Necessary, as these are static members
 | 
					
						
							|  |  |  |   // (they really shouldn't be and should be refactored at some point).
 | 
					
						
							|  |  |  |   m_virtualXFBList.clear(); | 
					
						
							|  |  |  |   m_realXFBSource.reset(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, | 
					
						
							|  |  |  |                                                                  u32 fbHeight, u32* xfbCountP) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!g_ActiveConfig.bUseXFB) | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2011-03-19 00:21:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (g_ActiveConfig.bUseRealXFB) | 
					
						
							|  |  |  |     return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return GetVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCountP); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth, | 
					
						
							|  |  |  |                                                                      u32 fbHeight, u32* xfbCountP) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *xfbCountP = 1; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // recreate if needed
 | 
					
						
							|  |  |  |   if (m_realXFBSource && | 
					
						
							|  |  |  |       (m_realXFBSource->texWidth != fbWidth || m_realXFBSource->texHeight != fbHeight)) | 
					
						
							|  |  |  |     m_realXFBSource.reset(); | 
					
						
							| 
									
										
										
										
											2014-05-02 23:07:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!m_realXFBSource && g_framebuffer_manager) | 
					
						
							|  |  |  |     m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight, 1); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!m_realXFBSource) | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2015-11-21 10:45:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_realXFBSource->srcAddr = xfbAddr; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_realXFBSource->srcWidth = MAX_XFB_WIDTH; | 
					
						
							|  |  |  |   m_realXFBSource->srcHeight = MAX_XFB_HEIGHT; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_realXFBSource->texWidth = fbWidth; | 
					
						
							|  |  |  |   m_realXFBSource->texHeight = fbHeight; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_realXFBSource->sourceRc.left = 0; | 
					
						
							|  |  |  |   m_realXFBSource->sourceRc.top = 0; | 
					
						
							|  |  |  |   m_realXFBSource->sourceRc.right = fbWidth; | 
					
						
							|  |  |  |   m_realXFBSource->sourceRc.bottom = fbHeight; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Decode YUYV data from GameCube RAM
 | 
					
						
							|  |  |  |   m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_overlappingXFBArray[0] = m_realXFBSource.get(); | 
					
						
							|  |  |  |   return &m_overlappingXFBArray[0]; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | const XFBSourceBase* const* | 
					
						
							|  |  |  | FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32* xfbCountP) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 xfbCount = 0; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (m_virtualXFBList.empty())  // no Virtual XFBs available
 | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 srcLower = xfbAddr; | 
					
						
							|  |  |  |   u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   VirtualXFBListType::reverse_iterator it = m_virtualXFBList.rbegin(), | 
					
						
							|  |  |  |                                        vlend = m_virtualXFBList.rend(); | 
					
						
							|  |  |  |   for (; it != vlend; ++it) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     VirtualXFB* vxfb = &*it; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     u32 dstLower = vxfb->xfbAddr; | 
					
						
							|  |  |  |     u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     if (AddressRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_overlappingXFBArray[xfbCount] = vxfb->xfbSource.get(); | 
					
						
							|  |  |  |       ++xfbCount; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   *xfbCountP = xfbCount; | 
					
						
							|  |  |  |   return &m_overlappingXFBArray[0]; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, | 
					
						
							|  |  |  |                                        const EFBRectangle& sourceRc, float Gamma) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (g_ActiveConfig.bUseRealXFB) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (g_framebuffer_manager) | 
					
						
							|  |  |  |       g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     CopyToVirtualXFB(xfbAddr, fbStride, fbHeight, sourceRc, Gamma); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, | 
					
						
							|  |  |  |                                               const EFBRectangle& sourceRc, float Gamma) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!g_framebuffer_manager) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, sourceRc.GetWidth(), fbHeight); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m_virtualXFBList.end() == vxfb) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // create a new Virtual XFB and place it at the front of the list
 | 
					
						
							|  |  |  |       m_virtualXFBList.emplace_front(); | 
					
						
							|  |  |  |       vxfb = m_virtualXFBList.begin(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // Replace the last virtual XFB
 | 
					
						
							|  |  |  |       --vxfb; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // else // replace existing virtual XFB
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // move this Virtual XFB to the front of the list.
 | 
					
						
							|  |  |  |   if (m_virtualXFBList.begin() != vxfb) | 
					
						
							|  |  |  |     m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 12:31:20 -05:00
										 |  |  |   u32 target_width, target_height; | 
					
						
							|  |  |  |   std::tie(target_width, target_height) = g_framebuffer_manager->GetTargetSize(); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // recreate if needed
 | 
					
						
							|  |  |  |   if (vxfb->xfbSource && | 
					
						
							|  |  |  |       (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height)) | 
					
						
							|  |  |  |     vxfb->xfbSource.reset(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!vxfb->xfbSource) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     vxfb->xfbSource = | 
					
						
							|  |  |  |         g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers); | 
					
						
							|  |  |  |     if (!vxfb->xfbSource) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vxfb->xfbSource->texWidth = target_width; | 
					
						
							|  |  |  |     vxfb->xfbSource->texHeight = target_height; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr; | 
					
						
							|  |  |  |   vxfb->xfbSource->srcWidth = vxfb->xfbWidth = sourceRc.GetWidth(); | 
					
						
							|  |  |  |   vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // keep stale XFB data from being used
 | 
					
						
							|  |  |  |   ReplaceVirtualXFB(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Copy EFB data to XFB and restore render target again
 | 
					
						
							|  |  |  |   vxfb->xfbSource->CopyEFB(Gamma); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | FramebufferManagerBase::VirtualXFBListType::iterator | 
					
						
							|  |  |  | FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   const u32 srcLower = xfbAddr; | 
					
						
							|  |  |  |   const u32 srcUpper = xfbAddr + 2 * width * height; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return std::find_if(m_virtualXFBList.begin(), m_virtualXFBList.end(), | 
					
						
							|  |  |  |                       [srcLower, srcUpper](const VirtualXFB& xfb) { | 
					
						
							|  |  |  |                         const u32 dstLower = xfb.xfbAddr; | 
					
						
							|  |  |  |                         const u32 dstUpper = xfb.xfbAddr + 2 * xfb.xfbWidth * xfb.xfbHeight; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |                         return dstLower >= srcLower && dstUpper <= srcUpper; | 
					
						
							|  |  |  |                       }); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FramebufferManagerBase::ReplaceVirtualXFB() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   VirtualXFBListType::iterator it = m_virtualXFBList.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const s32 srcLower = it->xfbAddr; | 
					
						
							|  |  |  |   const s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; | 
					
						
							|  |  |  |   const s32 lineSize = 2 * it->xfbWidth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ++it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (; it != m_virtualXFBList.end(); ++it) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     s32 dstLower = it->xfbAddr; | 
					
						
							|  |  |  |     s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dstLower >= srcLower && dstUpper <= srcUpper) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // Invalidate the data
 | 
					
						
							|  |  |  |       it->xfbAddr = 0; | 
					
						
							|  |  |  |       it->xfbHeight = 0; | 
					
						
							|  |  |  |       it->xfbWidth = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (AddressRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       s32 upperOverlap = (srcUpper - dstLower) / lineSize; | 
					
						
							|  |  |  |       s32 lowerOverlap = (dstUpper - srcLower) / lineSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (upperOverlap > 0 && lowerOverlap < 0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         it->xfbAddr += lineSize * upperOverlap; | 
					
						
							|  |  |  |         it->xfbHeight -= upperOverlap; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (lowerOverlap > 0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         it->xfbHeight -= lowerOverlap; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-25 00:58:16 +01:00
										 |  |  | int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x) | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (g_ActiveConfig.RealXFBEnabled()) | 
					
						
							|  |  |  |     return x; | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return x * (int)Renderer::GetTargetRectangle().GetWidth() / | 
					
						
							|  |  |  |          (int)FramebufferManagerBase::LastXfbWidth(); | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-25 00:58:16 +01:00
										 |  |  | int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y) | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (g_ActiveConfig.RealXFBEnabled()) | 
					
						
							|  |  |  |     return y; | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return y * (int)Renderer::GetTargetRectangle().GetHeight() / | 
					
						
							|  |  |  |          (int)FramebufferManagerBase::LastXfbHeight(); | 
					
						
							| 
									
										
										
										
											2012-09-29 00:19:28 +02:00
										 |  |  | } |