// Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once #include #include "gfx/gl_common.h" #include "gfx_es2/fbo.h" // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw // pixel data. #include "../Globals.h" #include "GPU/GPUCommon.h" struct GLSLProgram; class TextureCache; enum { FB_USAGE_DISPLAYED_FRAMEBUFFER = 1, FB_USAGE_RENDERTARGET = 2, FB_USAGE_TEXTURE = 4, }; enum { GPU_VENDOR_NVIDIA = 1, GPU_VENDOR_AMD = 2, GPU_VENDOR_INTEL = 3, GPU_VENDOR_ARM = 4, GPU_VENDOR_POWERVR = 5, GPU_VENDOR_ADRENO = 6, GPU_VENDOR_UNKNOWN = 0, }; enum { FB_NON_BUFFERED_MODE = 0, FB_BUFFERED_MODE = 1, #ifndef USING_GLES2 FB_READFBOMEMORY_CPU = 2, FB_READFBOMEMORY_GPU = 3, #else FB_READFBOMEMORY_GPU = 2, #endif }; struct VirtualFramebuffer { int last_frame_used; u32 fb_address; u32 z_address; int fb_stride; int z_stride; // There's also a top left of the drawing region, but meh... // width/height: The detected size of the current framebuffer. u16 width; u16 height; // renderWidth/renderHeight: The actual size we render at. May be scaled to render at higher resolutions. u16 renderWidth; u16 renderHeight; // bufferWidth/bufferHeight: The actual (but non scaled) size of the buffer we render to. May only be bigger than width/height. u16 bufferWidth; u16 bufferHeight; u16 usageFlags; GEBufferFormat format; // virtual, right now they are all RGBA8888 FBOColorDepth colorDepth; FBO *fbo; bool dirtyAfterDisplay; }; void CenterRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH); #ifndef USING_GLES2 // Simple struct for asynchronous PBO readbacks struct AsyncPBO { GLuint handle; u32 maxSize; u32 fb_address; u32 stride; u32 height; u32 size; GEBufferFormat format; bool reading; }; #endif class ShaderManager; class FramebufferManager { public: FramebufferManager(); ~FramebufferManager(); void SetTextureCache(TextureCache *tc) { textureCache_ = tc; } void SetShaderManager(ShaderManager *sm) { shaderManager_ = sm; } void DrawPixels(const u8 *framebuf, GEBufferFormat pixelFormat, int linesize); void DrawActiveTexture(float x, float y, float w, float h, bool flip = false, float uscale = 1.0f, float vscale = 1.0f, GLSLProgram *program = 0); void DestroyAllFBOs(); void DecimateFBOs(); void BeginFrame(); void EndFrame(); void Resized(); void DeviceLost(); void CopyDisplayToOutput(); void SetRenderFrameBuffer(); // Uses parameters computed from gstate void UpdateFromMemory(u32 addr, int size); void ReadFramebufferToMemory(VirtualFramebuffer *vfb); // TODO: Break out into some form of FBO manager VirtualFramebuffer *GetDisplayFBO(); void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format); size_t NumVFBs() const { return vfbs_.size(); } std::vector GetFramebufferList(); int GetRenderWidth() const { return currentRenderVfb_ ? currentRenderVfb_->renderWidth : 480; } int GetRenderHeight() const { return currentRenderVfb_ ? currentRenderVfb_->renderHeight : 272; } int GetTargetWidth() const { return currentRenderVfb_ ? currentRenderVfb_->width : 480; } int GetTargetHeight() const { return currentRenderVfb_ ? currentRenderVfb_->height : 272; } u32 PrevDisplayFramebufAddr() { return prevDisplayFramebuf_ ? (0x04000000 | prevDisplayFramebuf_->fb_address) : 0; } u32 DisplayFramebufAddr() { return displayFramebuf_ ? (0x04000000 | displayFramebuf_->fb_address) : 0; } void DestroyFramebuf(VirtualFramebuffer *vfb); private: void CompileDraw2DProgram(); u32 ramDisplayFramebufPtr_; // workaround for MotoGP insanity u32 displayFramebufPtr_; u32 displayStride_; GEBufferFormat displayFormat_; VirtualFramebuffer *displayFramebuf_; VirtualFramebuffer *prevDisplayFramebuf_; VirtualFramebuffer *prevPrevDisplayFramebuf_; int frameLastFramebufUsed; std::vector vfbs_; VirtualFramebuffer *currentRenderVfb_; // Used by ReadFramebufferToMemory void BlitFramebuffer_(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool flip = false, float upscale = 1.0f, float vscale = 1.0f); #ifndef USING_GLES2 void PackFramebufferGL_(VirtualFramebuffer *vfb); #endif void PackFramebufferGLES_(VirtualFramebuffer *vfb); int gpuVendor; std::vector bvfbs_; // blitting FBOs #ifndef USING_GLES2 AsyncPBO *pixelBufObj_; //this isn't that large u8 currentPBO_; #endif // Used by DrawPixels unsigned int drawPixelsTex_; GEBufferFormat drawPixelsTexFormat_; u8 *convBuf; GLSLProgram *draw2dprogram; TextureCache *textureCache_; ShaderManager *shaderManager_; bool resized_; bool useBufferedRendering_; };