open source
This commit is contained in:
@@ -0,0 +1,627 @@
|
||||
/**
|
||||
@file JCPerfHUD.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_18
|
||||
*/
|
||||
|
||||
#include "JCPerfHUD.h"
|
||||
#include <util/Log.h>
|
||||
#include <util/JCCommonMethod.h>
|
||||
#include "../LayaGL/JCLayaGL.h"
|
||||
#if __APPLE__
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#else
|
||||
#include <GLES3/gl3.h>
|
||||
#endif
|
||||
namespace laya
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
int JCPerfHUD::m_nMaxData=100;
|
||||
double JCPerfHUD::m_tmCurRender =0;
|
||||
double JCPerfHUD::m_tmDelayTime = 0;
|
||||
PerfDataBase* JCPerfHUD::m_vDatas[MAXPERFDATA];
|
||||
std::vector<short> JCPerfHUD::m_vValidID;
|
||||
double JCPerfHUD::m_tmCurJs;
|
||||
double JCPerfHUD::m_tmVSYNC = 0.0;
|
||||
unsigned int JCPerfHUD::m_nCurVsyncFrm = 0;
|
||||
unsigned int JCPerfHUD::m_nCurDrawFrm = 0;
|
||||
float JCPerfHUD::m_fGlobalScale = 1.0;
|
||||
JCLayaGL* JCPerfHUD::m_pLayaGL = NULL;
|
||||
void PerfData::updateData( float dt)
|
||||
{
|
||||
m_DataLock.lock();
|
||||
m_vDatas.push_back(dt);
|
||||
if (m_vDatas.size()>m_nMaxData) {
|
||||
m_vDatas.pop_front();
|
||||
}
|
||||
m_DataLock.unlock();
|
||||
}
|
||||
|
||||
//假设是均匀时间
|
||||
void PerfData::drawData(JCPerfDataRender* pRender) {
|
||||
m_DataLock.lock();
|
||||
JCPerfDataRender::vertex cdata[100];
|
||||
JCPerfDataRender::vertex* pCurVert = (JCPerfDataRender::vertex*)cdata;
|
||||
|
||||
int nPanelW = pRender->m_nWidth;
|
||||
auto it = m_vDatas.begin();
|
||||
int nXOff = m_nMaxData - m_vDatas.size(); //必然>=0
|
||||
float dx = ((float)nPanelW)/m_nMaxData;
|
||||
float cx = nXOff*dx;
|
||||
int num = 0;
|
||||
for (; it != m_vDatas.end(); it++) {
|
||||
cx += dx;
|
||||
pCurVert->x = cx;
|
||||
pCurVert->y = (*it)*m_fScale;
|
||||
pCurVert++;
|
||||
num++;
|
||||
if (num > 100) {//超出上面的buffer的最大值了,先画一下。
|
||||
pRender->draw2DLines((float*)cdata, num, m_nColor);
|
||||
num = 0;
|
||||
pCurVert = (JCPerfDataRender::vertex*)cdata;
|
||||
}
|
||||
}
|
||||
if(num>0)
|
||||
pRender->draw2DLines((float*)cdata, num, m_nColor);
|
||||
m_DataLock.unlock();
|
||||
}
|
||||
|
||||
void perfBarData::addData(double tm, float st, float ed) {
|
||||
m_DataLock.lock();
|
||||
m_vDatas.push_back({ tm,st,ed });
|
||||
if (m_vDatas.size() > m_nMaxData) {
|
||||
m_vDatas.pop_front();
|
||||
}
|
||||
m_DataLock.unlock();
|
||||
}
|
||||
|
||||
void perfBarData::drawData(JCPerfDataRender* pRender) {
|
||||
static dataType datas[100];
|
||||
m_DataLock.lock();
|
||||
int datanum = m_vDatas.size();
|
||||
auto it = m_vDatas.begin();
|
||||
int di = 0;
|
||||
for (int i = 0; i < datanum; i++) {
|
||||
datas[di++] = *it++;
|
||||
if (di > 100) {
|
||||
pRender->drawAsBarGraph((float*)datas, di, m_fScale, m_nColor);
|
||||
di = 0;
|
||||
}
|
||||
}
|
||||
if (di > 0) {
|
||||
pRender->drawAsBarGraph((float*)datas, di, m_fScale, m_nColor);
|
||||
}
|
||||
m_DataLock.unlock();
|
||||
}
|
||||
|
||||
ScopePerf::ScopePerf(int id)
|
||||
{
|
||||
m_t0 = tmGetCurms();
|
||||
m_nid=id;
|
||||
}
|
||||
ScopePerf::~ScopePerf()
|
||||
{
|
||||
float dt = (float)(tmGetCurms()-m_t0);
|
||||
JCPerfHUD::updateData(m_nid, dt);
|
||||
}
|
||||
void JCPerfHUD::init()
|
||||
{
|
||||
m_nMaxData=100;
|
||||
memset(m_vDatas, 0, sizeof(m_vDatas));
|
||||
addData(PHUD_FRAME_DELAY,0xffffffff,"PHUD_FRAME_DELAY", 1);
|
||||
addData(PHUD_RENDER_DELAY,0xffff0000,"PHUD_RENDER_DELAY", 1);
|
||||
addData(PHUD_JS_DELAY,0xff00ff00,"PHUD_JS_DELAY", 1);
|
||||
/*
|
||||
addData(new perfBarData(PHUD_BAR_JS_ONDRAW, 0x6600ff00, "jsbar",10.0f));
|
||||
addData(new perfBarData(PHUD_BAR_RENDER, 0x66ff0000, "renderbar",10.0f));
|
||||
addData(new perfBarData(PHUD_BAR_JSWAIT, 0x66003300, "jswait", 10.0f));
|
||||
addData(new perfBarData(PHUD_BAR_GLWAIT, 0x66660000, "glwait", 10.0f));
|
||||
*/
|
||||
}
|
||||
void JCPerfHUD::deleteInstance()
|
||||
{
|
||||
int nValidSize = JCPerfHUD::m_vValidID.size();
|
||||
for( int i=0; i < nValidSize ; i++ )
|
||||
{
|
||||
PerfData* pData =(PerfData*)JCPerfHUD::m_vDatas[JCPerfHUD::m_vValidID[i]];
|
||||
if( pData == NULL )continue;
|
||||
delete pData;
|
||||
}
|
||||
m_vValidID.clear();
|
||||
}
|
||||
|
||||
void JCPerfHUD::addVSyncFrame() {
|
||||
m_nCurVsyncFrm++;
|
||||
}
|
||||
void JCPerfHUD::addOnDrawFrame() {
|
||||
m_nCurDrawFrm++;
|
||||
}
|
||||
|
||||
void JCPerfHUD::resetFrame() {
|
||||
m_nCurVsyncFrm = 0;
|
||||
m_nCurDrawFrm = 0;
|
||||
}
|
||||
|
||||
|
||||
PerfData* JCPerfHUD::addData( int p_nId, int p_nColor,float scale ,float p_fAlert)
|
||||
{
|
||||
return addData(p_nId, p_nColor, "", scale, p_fAlert);
|
||||
}
|
||||
PerfData* JCPerfHUD::addData( int p_nId, int p_nColor,const char* p_sDesc,float scale, float p_fAlert )
|
||||
{
|
||||
if( p_nId < 0 || p_nId >= MAXPERFDATA )
|
||||
{
|
||||
LOGE("CPerfHUD::AddData超出最大数量 max=%d,cur=%d", MAXPERFDATA, p_nId );
|
||||
return NULL;
|
||||
}
|
||||
PerfData* pData = (PerfData*)m_vDatas[p_nId];
|
||||
if( pData == NULL )
|
||||
{
|
||||
pData = new PerfData( p_nId,p_nColor,p_sDesc );
|
||||
m_vDatas[p_nId]=pData;
|
||||
m_vValidID.push_back( p_nId );
|
||||
}
|
||||
pData->m_fScale = scale*m_fGlobalScale;
|
||||
pData->m_nMaxData=m_nMaxData;
|
||||
pData->m_nColor=p_nColor;
|
||||
pData->m_fAlert = p_fAlert;
|
||||
return pData;
|
||||
}
|
||||
|
||||
PerfDataBase* JCPerfHUD::addData(PerfDataBase* pData) {
|
||||
if (!pData)
|
||||
return nullptr;
|
||||
int id = pData->m_nID;
|
||||
pData->m_nMaxData = m_nMaxData;
|
||||
if (id < 0 || id >= MAXPERFDATA){
|
||||
LOGE("CPerfHUD::AddData超出最大数量 max=%d,cur=%d", MAXPERFDATA, id);
|
||||
return nullptr;
|
||||
}
|
||||
PerfDataBase* pCurData = m_vDatas[id];
|
||||
if (pCurData == NULL){
|
||||
m_vDatas[id] = pData;
|
||||
m_vValidID.push_back(id);
|
||||
}
|
||||
else {
|
||||
LOGE("已经存在数据了 %d , %s",((int)pCurData->m_nID), (pCurData->m_strDesc.c_str()));
|
||||
return pCurData;
|
||||
}
|
||||
return pData;
|
||||
}
|
||||
|
||||
void JCPerfHUD::delData(int p_nId)
|
||||
{
|
||||
if( p_nId < 0 || p_nId >= MAXPERFDATA )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
PerfDataBase* pData = m_vDatas[p_nId];
|
||||
if( pData != NULL )
|
||||
{
|
||||
delete m_vDatas[p_nId];
|
||||
m_vDatas[p_nId]=NULL;
|
||||
}
|
||||
std::vector<short>::iterator it = m_vValidID.begin();
|
||||
while( it!=m_vValidID.end() )
|
||||
{
|
||||
if(*it==p_nId)
|
||||
{
|
||||
it=m_vValidID.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
PerfDataBase* JCPerfHUD::getData( int id )
|
||||
{
|
||||
if( id<0 || id>=MAXPERFDATA){
|
||||
LOGE("JCPerfHUD::getData超出最大数量 max=%d,cur=%d", MAXPERFDATA, id );
|
||||
return NULL;
|
||||
}
|
||||
return m_vDatas[id];
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void JCPerfHUD::updateData( int p_nDataID, float p_fData )
|
||||
{
|
||||
if( p_nDataID<0 || p_nDataID>=MAXPERFDATA)
|
||||
{
|
||||
LOGE("JCPerfHUD::updateData超出最大数量 max=%d,cur=%d", MAXPERFDATA, p_nDataID );
|
||||
return ;
|
||||
}
|
||||
if(m_vDatas[p_nDataID])
|
||||
{
|
||||
((PerfData*)m_vDatas[p_nDataID])->updateData(p_fData);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
JCPerfDataRender::JCPerfDataRender()
|
||||
{
|
||||
m_nOffY = 100;
|
||||
m_nOffX = 100;
|
||||
m_nWidth = 400;
|
||||
m_nHeight = 400;
|
||||
m_nProgram = 0;
|
||||
m_nVSShader = 0;
|
||||
m_nPSShader = 0;
|
||||
m_sVSShader = R"(
|
||||
attribute vec3 g_Position;
|
||||
void main(){
|
||||
gl_Position = vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);
|
||||
})";
|
||||
m_sPSShader = R"(
|
||||
precision mediump float;
|
||||
uniform vec4 color;
|
||||
void main(){
|
||||
gl_FragColor = color;
|
||||
})";
|
||||
|
||||
}
|
||||
JCPerfDataRender::~JCPerfDataRender()
|
||||
{
|
||||
m_kVBOManager.ReleaseVBO();
|
||||
releaseGPUShader();
|
||||
}
|
||||
void JCPerfDataRender::validateGPUShader()
|
||||
{
|
||||
if (m_nProgram <= 0)
|
||||
{
|
||||
m_nVSShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
const GLchar* sVSSource = m_sVSShader.c_str();
|
||||
glShaderSource(m_nVSShader, 1, &sVSSource, NULL);
|
||||
glCompileShader(m_nVSShader);
|
||||
m_nPSShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
const GLchar* sPSSource = m_sPSShader.c_str();
|
||||
glShaderSource(m_nPSShader, 1, &sPSSource, NULL);
|
||||
glCompileShader(m_nPSShader);
|
||||
m_nProgram = glCreateProgram();
|
||||
glAttachShader(m_nProgram, m_nVSShader);
|
||||
glAttachShader(m_nProgram, m_nPSShader);
|
||||
glLinkProgram(m_nProgram);
|
||||
}
|
||||
}
|
||||
void JCPerfDataRender::releaseGPUShader()
|
||||
{
|
||||
if (m_nProgram)glDeleteProgram(m_nProgram);
|
||||
if (m_nProgram)glDeleteShader(m_nVSShader);
|
||||
if (m_nProgram)glDeleteShader(m_nPSShader);
|
||||
m_nProgram = 0;
|
||||
m_nVSShader = 0;
|
||||
m_nPSShader = 0;
|
||||
}
|
||||
void JCPerfDataRender::drawData()
|
||||
{
|
||||
m_tmDrawTm = tmGetCurms();
|
||||
|
||||
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
|
||||
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
//last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
|
||||
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
|
||||
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
|
||||
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
|
||||
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
|
||||
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
|
||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
||||
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||
GLboolean last_color_write_mask[4];
|
||||
glGetBooleanv(GL_COLOR_WRITEMASK, last_color_write_mask);
|
||||
|
||||
GLint vb0enabled = 0;
|
||||
GLint vb0size = 0;
|
||||
GLint vb0type = 0;
|
||||
GLint vb0normalized = 0;
|
||||
GLint vb0stride = 0;
|
||||
GLint vb0bufferbinding = 0;
|
||||
void *vb0pointer = 0;
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vb0enabled);
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vb0size);
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vb0type);
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vb0normalized);
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vb0stride);
|
||||
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vb0bufferbinding);
|
||||
glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vb0pointer);
|
||||
|
||||
glColorMask(true, true, true, true);
|
||||
JCLayaGL::_bindVertexArray(0);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glViewport(0, 0, JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth, JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight);
|
||||
|
||||
validateGPUShader();
|
||||
glUseProgram(m_nProgram);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
draw2DRect(0,0,(float)m_nWidth,(float)m_nHeight,0x66000000 );
|
||||
//刻度
|
||||
float maxx= (float)m_nWidth;
|
||||
float k[4];
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 0;
|
||||
k[2]=maxx;
|
||||
k[3] = 0;
|
||||
draw2DLines( k,2,0xff336633);
|
||||
k[0] = 0;
|
||||
k[1] = 10.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2]=maxx;
|
||||
k[3] = 10.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k,2, 0x55ffff00);
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 16.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2]=maxx;
|
||||
k[3] = 16.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k,2,0x55ff0000);
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 33.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2] = maxx;
|
||||
k[3] = 33.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k, 2, 0x55ffff00);
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 50.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2]=maxx;
|
||||
k[3] = 50.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k,2, 0x550000ff);
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 100.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2]=maxx;
|
||||
k[3] = 100.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k,2, 0x550000ff);
|
||||
|
||||
k[0] = 0;
|
||||
k[1] = 167.0f*JCPerfHUD::m_fGlobalScale;
|
||||
k[2] = maxx;
|
||||
k[3] = 167.0f*JCPerfHUD::m_fGlobalScale;
|
||||
draw2DLines(k, 2, 0x550000ff);
|
||||
|
||||
//数据
|
||||
int nValidSize = JCPerfHUD::m_vValidID.size();
|
||||
for( int i=0; i < nValidSize ; i++ ){
|
||||
PerfDataBase* pData =JCPerfHUD::m_vDatas[JCPerfHUD::m_vValidID[i]];
|
||||
if( pData == NULL )continue;
|
||||
pData->drawData(this);
|
||||
}
|
||||
// Restore
|
||||
glUseProgram(last_program);
|
||||
JCLayaGL::_bindVertexArray(last_vertex_array);
|
||||
|
||||
if (vb0enabled)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
glVertexAttribPointer(0, vb0size, vb0type, vb0normalized, vb0stride, vb0pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableVertexAttribArray(0);
|
||||
}
|
||||
glColorMask(last_color_write_mask[0], last_color_write_mask[1], last_color_write_mask[2], last_color_write_mask[3]);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
|
||||
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
||||
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
||||
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
//glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
|
||||
}
|
||||
void JCPerfDataRender::invalidGLRes()
|
||||
{
|
||||
m_kVBOManager.freeGLResource();
|
||||
releaseGPUShader();
|
||||
}
|
||||
|
||||
/*
|
||||
数据的x轴单位是帧
|
||||
*/
|
||||
void JCPerfDataRender::draw2DLines( float* p_pVerts, int vertnum, unsigned int p_nColor)
|
||||
{
|
||||
if (vertnum < 2)
|
||||
return;
|
||||
int nVBO = m_kVBOManager.GetVBO();
|
||||
if (nVBO <= 0)
|
||||
{
|
||||
LOGE("JCPerfDataRender::draw2DLines error, createvbo error!");
|
||||
return;
|
||||
}
|
||||
static vertex tmpvertex[1000];
|
||||
float color[4];
|
||||
color[3] = ((p_nColor & 0xff000000) >> 24) / 255.0f;;
|
||||
color[0] = ((p_nColor & 0x00ff0000) >> 16) / 255.0f; //r
|
||||
color[1] = ((p_nColor & 0x0000ff00) >> 8) / 255.0f; //g
|
||||
color[2] = (p_nColor & 0x000000ff) / 255.0f; //b
|
||||
int nVertNum = vertnum > 1000 ? 1000 : vertnum;
|
||||
for (int i = 0; i < nVertNum; i++)
|
||||
{
|
||||
float cx = *p_pVerts++;
|
||||
float cy = *p_pVerts++;
|
||||
cx = m_nOffX+cx;
|
||||
cy = m_nOffY + m_nHeight - cy;
|
||||
cx = (float)((cx*2.0 / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0);
|
||||
cy = (float)(-(cy*2.0 / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0);
|
||||
tmpvertex[i].x = cx;
|
||||
tmpvertex[i].y = cy;
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, nVertNum*sizeof(vertex), tmpvertex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform4fv(0, 1, color);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, vertnum);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCPerfDataRender::draw2DRect(float x, float y, float w, float h, unsigned int p_nColor)
|
||||
{
|
||||
int nVBO = m_kVBOManager.GetVBO();
|
||||
if (nVBO <= 0)
|
||||
{
|
||||
LOGE("JCPerfDataRender::draw2DRect error, createvbo error!");
|
||||
return;
|
||||
}
|
||||
float color[4];
|
||||
color[3] = ((p_nColor & 0xff000000)>>24)/ 255.0f;
|
||||
color[0] = ((p_nColor & 0x00ff0000) >> 16) / 255.0f; //r
|
||||
color[1] = ((p_nColor & 0x0000ff00) >> 8) / 255.0f; //g
|
||||
color[2] = (p_nColor & 0x000000ff) / 255.0f; //b
|
||||
|
||||
static vertex tmpvertex[4];
|
||||
int nVertNum = 4;
|
||||
|
||||
//下面的是错误的。可能会导致严重的丢失精度
|
||||
tmpvertex[0].x = x;
|
||||
tmpvertex[0].y = y;
|
||||
|
||||
tmpvertex[1].x = (x + w);
|
||||
tmpvertex[1].y = y;
|
||||
|
||||
tmpvertex[2].x = (x + w);
|
||||
tmpvertex[2].y = (y + h);
|
||||
|
||||
tmpvertex[3].x = x;
|
||||
tmpvertex[3].y = (y + h);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float cx = tmpvertex[i].x+m_nOffX;
|
||||
float cy = tmpvertex[i].y+m_nOffY;
|
||||
|
||||
cx = (float)((cx*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0f);
|
||||
cy = (float)(-(cy*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0f);
|
||||
|
||||
tmpvertex[i].x = cx;
|
||||
tmpvertex[i].y = cy;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, nVertNum*sizeof(vertex), tmpvertex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform4fv(0, 1, color);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
数据的x轴单位是时间,ms。
|
||||
*/
|
||||
void JCPerfDataRender::drawAsBarGraph(float* pData, int p_nDataNum, float scale, unsigned int p_nColor) {
|
||||
if (p_nDataNum <= 1)
|
||||
return;
|
||||
int nVBO = m_kVBOManager.GetVBO();
|
||||
if (nVBO <= 0){
|
||||
LOGE("JCPerfDataRender::draw2DLines error, createvbo error!");
|
||||
return;
|
||||
}
|
||||
static vertex tmpvertex[1000];
|
||||
vertex* pCurVert = tmpvertex;
|
||||
float color[4];
|
||||
color[3] = ((p_nColor & 0xff000000) >> 24) / 255.0f;
|
||||
color[0] = ((p_nColor & 0x00ff0000) >> 16) / 255.0f; //r
|
||||
color[1] = ((p_nColor & 0x0000ff00) >> 8) / 255.0f; //g
|
||||
color[2] = (p_nColor & 0x000000ff) / 255.0f; //b
|
||||
perfBarData::dataType* pBarData = (perfBarData::dataType*)pData;
|
||||
//从当前时间倒退displayDuration ms,整个图形的,左边是m_tmDrawTm - displayDuration, 右边是 m_tmDrawTm
|
||||
static double displayDuration = 4000.0;
|
||||
double sttm = m_tmDrawTm - displayDuration;// pBarData[0].tm;
|
||||
//float edtm = pBarData[p_nDataNum - 1].tm;
|
||||
float dataduration = (float)displayDuration;//固定4秒钟。 edtm - sttm + 16.667f; //左右各加半个
|
||||
float barwidth = m_nWidth/(dataduration/16.6667f);
|
||||
float foffx = (float)m_nOffX;
|
||||
float foffy = (float)m_nOffY;
|
||||
int nVertNum = 0;
|
||||
for (int i = 0; i < p_nDataNum; i++, pBarData++) {
|
||||
if (pBarData->tm < sttm)
|
||||
continue;
|
||||
float cx = foffx + ((float)(pBarData->tm - sttm))*m_nWidth/ dataduration;
|
||||
float ltx = cx;
|
||||
float lty = foffy + m_nHeight - (pBarData->start + pBarData->duration)*scale;
|
||||
float rbx = cx + barwidth;
|
||||
float rby = foffy + m_nHeight - pBarData->start*scale;
|
||||
if (rby - lty < 1.0f)//大小不要为0,否则看不到了
|
||||
rby = lty + 1.0f;
|
||||
|
||||
ltx = ((ltx*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0f);
|
||||
lty = (-(lty*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0f);
|
||||
rbx = ((rbx*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0f);
|
||||
rby = (-(rby*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0f);
|
||||
|
||||
pCurVert->x = ltx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = rby; pCurVert++;
|
||||
pCurVert->x = ltx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = rby; pCurVert++;
|
||||
pCurVert->x = ltx; pCurVert->y = rby; pCurVert++;
|
||||
nVertNum += 6;
|
||||
if (nVertNum >= 1000 - 6) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, nVertNum*sizeof(vertex), tmpvertex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform4fv(0, 1, color);
|
||||
glDrawArrays(GL_TRIANGLES, 0, nVertNum);
|
||||
nVertNum = 0;
|
||||
pCurVert = tmpvertex;
|
||||
}
|
||||
//再把下一段画到上面
|
||||
if (true) {
|
||||
perfBarData::dataType* pBarDataN =(i<p_nDataNum-1)?(pBarData + 1):pBarData;
|
||||
float cx = foffx + ((float)(pBarData->tm - sttm))*m_nWidth / dataduration;//这个时间要用当前的
|
||||
float ltx = cx;
|
||||
float lty = foffy + m_nHeight - (pBarDataN->start + pBarDataN->duration+16.6667f)*scale;
|
||||
float rbx = cx + barwidth;
|
||||
float rby = foffy + m_nHeight - (pBarDataN->start+(float)(pBarDataN->tm-pBarData->tm))*scale;
|
||||
if (rby - lty < 1.0f)//大小不要为0,否则看不到了
|
||||
rby = lty + 1.0f;
|
||||
|
||||
ltx = ((ltx*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0f);
|
||||
lty = (-(lty*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0f);
|
||||
rbx = ((rbx*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasWidth) - 1.0f);
|
||||
rby = (-(rby*2.0f / JCPerfHUD::m_pLayaGL->m_nMainCanvasHeight) + 1.0f);
|
||||
|
||||
pCurVert->x = ltx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = rby; pCurVert++;
|
||||
pCurVert->x = ltx; pCurVert->y = lty; pCurVert++;
|
||||
pCurVert->x = rbx; pCurVert->y = rby; pCurVert++;
|
||||
pCurVert->x = ltx; pCurVert->y = rby; pCurVert++;
|
||||
nVertNum += 6;
|
||||
if (nVertNum >= 1000 - 6) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, nVertNum*sizeof(vertex), tmpvertex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform4fv(0, 1, color);
|
||||
glDrawArrays(GL_TRIANGLES, 0, nVertNum);
|
||||
nVertNum = 0;
|
||||
pCurVert = tmpvertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nVertNum > 0) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, nVertNum*sizeof(vertex), tmpvertex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glUniform4fv(0, 1, color);
|
||||
glDrawArrays(GL_TRIANGLES, 0, nVertNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
@file JCPerfHUD.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_18
|
||||
*/
|
||||
#ifndef __JCPerfHUD_H__
|
||||
#define __JCPerfHUD_H__
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "JCVBOManager.h"
|
||||
#include <mutex>
|
||||
#include <util/Log.h>
|
||||
#define USEPERF
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCLayaGL;
|
||||
class JCPerfDataRender;
|
||||
struct PerfDataBase{
|
||||
short m_nID=0;
|
||||
int m_nColor=0xff000000;
|
||||
std::string m_strDesc;
|
||||
unsigned short m_nMaxData=100;
|
||||
float m_fScale=1.0f; //渲染时候用
|
||||
virtual void drawData(JCPerfDataRender*) {};
|
||||
};
|
||||
/*
|
||||
记录一些变量的一定个数的历史记录。并提供画出来的功能。
|
||||
需要效率尽量高,因此,没有足够的封装和保护
|
||||
用数组而没用map
|
||||
每次updatedata都是累加数据,渲染完了之后,就会清0
|
||||
*/
|
||||
#define MAXPERFDATA 256
|
||||
struct PerfData:public PerfDataBase{
|
||||
PerfData(int id,int color, const char* pdesc){
|
||||
m_nID=id;
|
||||
m_strDesc=pdesc;
|
||||
m_nColor = color;
|
||||
}
|
||||
//添加或者累加数据 如果是新的一帧就添加,如果本帧已经有数据了,就累加
|
||||
void updateData( float dt);
|
||||
|
||||
virtual void drawData(JCPerfDataRender* pRender);
|
||||
public:
|
||||
std::list<float> m_vDatas;
|
||||
float m_fAlert=0.0f;
|
||||
std::mutex m_DataLock;
|
||||
};
|
||||
|
||||
class perfBarData :public PerfDataBase {
|
||||
public:
|
||||
struct dataType{
|
||||
double tm;
|
||||
float start, duration;
|
||||
dataType() {
|
||||
tm = start = duration = 0.0f;
|
||||
}
|
||||
dataType(double t, float st, float ed) {
|
||||
tm = t;
|
||||
start = st;
|
||||
duration = ed - st;
|
||||
}
|
||||
};
|
||||
|
||||
perfBarData(int id, int color, const char* pdesc,float scale) {
|
||||
m_nID = id;
|
||||
m_strDesc = pdesc;
|
||||
m_nColor = color;
|
||||
m_fScale = scale;
|
||||
}
|
||||
|
||||
void addData(double tm, float st, float ed);
|
||||
virtual void drawData(JCPerfDataRender* pRender);
|
||||
private:
|
||||
std::list<dataType> m_vDatas;
|
||||
std::mutex m_DataLock;
|
||||
};
|
||||
|
||||
/** @brief RenderGroup组的定义
|
||||
*
|
||||
*/
|
||||
class ScopePerf
|
||||
{
|
||||
public:
|
||||
double m_t0;
|
||||
int m_nid;
|
||||
ScopePerf(int id);
|
||||
~ScopePerf();
|
||||
};
|
||||
|
||||
#ifdef USEPERF
|
||||
#define PERF_INITVAR(var) auto var = tmGetCurms();
|
||||
#define PERF_UPDATE_DTIME(dataid,var,dt) \
|
||||
{ auto curtm = tmGetCurms(); \
|
||||
if( var==0)var = curtm; \
|
||||
dt = (curtm-var); \
|
||||
JCPerfHUD::updateData(dataid,dt); \
|
||||
var = curtm;}
|
||||
#define PERF_UPDATE_DATA(dataid,val) {JCPerfHUD::updateData(dataid,val);}
|
||||
#define PERF_SCOPE(id) ScopePerf scopeperf(id);
|
||||
#else
|
||||
#define PERF_INITVAR(var)
|
||||
#define PERF_UPDATE_DTIME(dataid,var)
|
||||
#define PERF_UPDATE_DATA(dataid,val)
|
||||
#define PERF_SCOPE(id)
|
||||
#endif
|
||||
|
||||
class JCPerfHUD
|
||||
{
|
||||
public:
|
||||
enum PERFHUD_TYPE
|
||||
{
|
||||
PHUD_FRAME_DELAY=0,
|
||||
PHUD_RENDER_DELAY,
|
||||
PHUD_JS_DELAY,
|
||||
PHUD_BAR_JS_ONDRAW,
|
||||
PHUD_BAR_RENDER,
|
||||
PHUD_BAR_JSWAIT,
|
||||
PHUD_BAR_GLWAIT,
|
||||
//TODO 现在只是内部使用。导出给js以后,要注意id的冲突的问题。
|
||||
};
|
||||
public:
|
||||
|
||||
static void init();
|
||||
|
||||
static void deleteInstance();
|
||||
|
||||
static PerfData* addData(int id, int color,float scale, float p_fAlert=0);
|
||||
|
||||
static PerfData* addData(int id, int color,const char* pdesc, float scale, float p_fAlert=0);
|
||||
|
||||
static PerfDataBase* addData(PerfDataBase* pPerfData);
|
||||
|
||||
static void delData(int id);
|
||||
|
||||
static PerfDataBase* getData(int id);
|
||||
|
||||
static void updateData(int p_nDataID, float p_fData);
|
||||
|
||||
static void addOnDrawFrame();
|
||||
static void addVSyncFrame();
|
||||
static void resetFrame();
|
||||
public:
|
||||
|
||||
static PerfDataBase* m_vDatas[MAXPERFDATA];
|
||||
static std::vector<short> m_vValidID; //有效ID,避免遍历m_Datas
|
||||
static int m_nMaxData;
|
||||
static double m_tmCurRender;
|
||||
static double m_tmDelayTime;
|
||||
static double m_tmCurJs;
|
||||
static double m_tmVSYNC;
|
||||
static unsigned int m_nCurVsyncFrm; //vsync帧数
|
||||
static unsigned int m_nCurDrawFrm; //实际触发onDraw的帧数
|
||||
static float m_fGlobalScale;
|
||||
static JCLayaGL* m_pLayaGL;
|
||||
};
|
||||
|
||||
class JCPerfDataRender
|
||||
{
|
||||
public:
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
JCPerfDataRender();
|
||||
~JCPerfDataRender();
|
||||
void drawData();
|
||||
void draw2DLines(float* p_pVerts, int vertnum, unsigned int p_nColor);
|
||||
void draw2DRect(float x, float y, float w, float h, unsigned int p_nColor );
|
||||
/*
|
||||
data:
|
||||
start,height 都是绝对值。与面板的大小同一单位
|
||||
*/
|
||||
void drawAsBarGraph(float* pData, int p_nDataNum, float scale, unsigned int p_nColor);
|
||||
void invalidGLRes();
|
||||
|
||||
private:
|
||||
|
||||
void validateGPUShader();
|
||||
|
||||
void releaseGPUShader();
|
||||
|
||||
private:
|
||||
|
||||
JCVBOManager m_kVBOManager;
|
||||
int m_nOffY;
|
||||
int m_nOffX;
|
||||
std::string m_sVSShader;
|
||||
std::string m_sPSShader;
|
||||
GLuint m_nVSShader;
|
||||
GLuint m_nPSShader;
|
||||
GLuint m_nProgram;
|
||||
double m_tmDrawTm; //当前渲染的时候的时间。用来处理跟时间相关的数据
|
||||
public:
|
||||
int m_nWidth; //面板的大小
|
||||
int m_nHeight; //面板的大小
|
||||
};
|
||||
|
||||
}
|
||||
#endif //__JCPerfHUD_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
@file JCVBOMgr.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_18
|
||||
*/
|
||||
|
||||
#include "JCVBOManager.h"
|
||||
|
||||
namespace laya
|
||||
{
|
||||
JCVBOManager::JCVBOManager()
|
||||
{
|
||||
m_nVBOSize = 10240;
|
||||
m_nCurVBOId = 0;
|
||||
m_vVBO.resize(20);
|
||||
m_bInited = false;
|
||||
}
|
||||
int JCVBOManager::GetVBO()
|
||||
{
|
||||
if (!m_bInited)
|
||||
{
|
||||
int nSize = m_vVBO.size();
|
||||
for (int i = 0; i < nSize; i++)
|
||||
{
|
||||
m_vVBO[i] = createVertexBuffer(m_nVBOSize);
|
||||
}
|
||||
m_bInited = true;
|
||||
}
|
||||
int vbo = m_vVBO[m_nCurVBOId];
|
||||
m_nCurVBOId++;
|
||||
if (m_vVBO.size())
|
||||
{
|
||||
m_nCurVBOId %= m_vVBO.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nCurVBOId = 0;
|
||||
}
|
||||
return vbo;
|
||||
}
|
||||
void JCVBOManager::freeGLResource()
|
||||
{
|
||||
int nSize = m_vVBO.size();
|
||||
glDeleteBuffers(nSize, (const GLuint*)&m_vVBO[0]);
|
||||
m_bInited = false;
|
||||
}
|
||||
void JCVBOManager::ReleaseVBO()
|
||||
{
|
||||
m_bInited = false;
|
||||
m_nCurVBOId = 0;
|
||||
}
|
||||
unsigned int JCVBOManager::createVertexBuffer( int totalSize )
|
||||
{
|
||||
unsigned int vbo = 0;
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,totalSize,0,GL_DYNAMIC_DRAW);
|
||||
return vbo;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
@file JCVBOMgr.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_18
|
||||
*/
|
||||
|
||||
#ifndef __JCVBOMgr_H__
|
||||
#define __JCVBOMgr_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#if __APPLE__
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#include <OpenGLES/ES3/glext.h>
|
||||
#else
|
||||
#include <GLES3/gl3.h>
|
||||
#endif
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCVBOManager
|
||||
{
|
||||
public:
|
||||
|
||||
JCVBOManager();
|
||||
|
||||
int GetVBO();
|
||||
|
||||
void ReleaseVBO();
|
||||
|
||||
unsigned int createVertexBuffer( int totalSize );
|
||||
|
||||
void freeGLResource();
|
||||
public:
|
||||
|
||||
std::vector<int> m_vVBO; //VBO
|
||||
int m_nVBOSize; //VBO的大小
|
||||
int m_nCurVBOId; //当前VBO的ID
|
||||
bool m_bInited; //是否初始化
|
||||
|
||||
};
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCVBOMgr_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
Reference in New Issue
Block a user