qglblitter: hide class definition

This commit is contained in:
sinamas 2013-03-10 18:13:47 +01:00
parent 13167187f9
commit 41877324b3
3 changed files with 155 additions and 165 deletions

View File

@ -17,6 +17,11 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "qglblitter.h" #include "qglblitter.h"
#include "../blitterwidget.h"
#include "../dwmcontrol.h"
#include "array.h"
#include "persistcheckbox.h"
#include "scoped_ptr.h"
#ifdef PLATFORM_WIN32 #ifdef PLATFORM_WIN32
#include <GL/glext.h> #include <GL/glext.h>
@ -31,12 +36,14 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
namespace {
enum { max_buffer_cnt = 3 }; enum { max_buffer_cnt = 3 };
class QGLBlitter::SubWidget : public QGLWidget { class SubWidget : public QGLWidget {
public: public:
SubWidget(QSize const &correctedSize, QSize const &textureSize, SubWidget(QSize const &correctedSize, QSize const &textureSize,
unsigned swapInterval, int dhzRefreshRate, bool bf, QGLBlitter *parent); unsigned swapInterval, int dhzRefreshRate, bool bf, BlitterWidget &parent);
long frameTimeEst() const { return ftEst_.est(); } long frameTimeEst() const { return ftEst_.est(); }
unsigned swapInterval() const { return swapInterval_; } unsigned swapInterval() const { return swapInterval_; }
void setBilinearFiltering(bool on); void setBilinearFiltering(bool on);
@ -88,10 +95,10 @@ static QGLFormat const getQGLFormat(unsigned const swapInterval) {
return f; return f;
} }
QGLBlitter::SubWidget::SubWidget(QSize const &correctedSize, QSize const &textureSize, SubWidget::SubWidget(QSize const &correctedSize, QSize const &textureSize,
unsigned swapInterval, int dhzRefreshRate, bool bf, unsigned swapInterval, int dhzRefreshRate, bool bf,
QGLBlitter *parent) BlitterWidget &parent)
: QGLWidget(getQGLFormat(swapInterval), parent) : QGLWidget(getQGLFormat(swapInterval), &parent)
, ftEst_(swapInterval * 10000000 / dhzRefreshRate) , ftEst_(swapInterval * 10000000 / dhzRefreshRate)
, correctedSize_(correctedSize) , correctedSize_(correctedSize)
, inSize_(textureSize) , inSize_(textureSize)
@ -115,11 +122,11 @@ static unsigned ceiledPow2(unsigned v) {
return v; return v;
} }
unsigned QGLBlitter::SubWidget::textureRes() const { unsigned SubWidget::textureRes() const {
return ceiledPow2(std::max(inSize_.width(), inSize_.height())); return ceiledPow2(std::max(inSize_.width(), inSize_.height()));
} }
void QGLBlitter::SubWidget::draw() { void SubWidget::draw() {
if (clear_) { if (clear_) {
--clear_; --clear_;
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -129,7 +136,7 @@ void QGLBlitter::SubWidget::draw() {
glFlush(); glFlush();
} }
void QGLBlitter::SubWidget::initializeGL() { void SubWidget::initializeGL() {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glShadeModel(GL_FLAT); glShadeModel(GL_FLAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -162,16 +169,16 @@ void QGLBlitter::SubWidget::initializeGL() {
initialized_ = true; initialized_ = true;
} }
void QGLBlitter::SubWidget::paintGL() { void SubWidget::paintGL() {
clear_ = max_buffer_cnt; clear_ = max_buffer_cnt;
if (static_cast<QGLBlitter const *>(parentWidget())->isPaused()) { if (static_cast<BlitterWidget const *>(parentWidget())->isPaused()) {
draw(); draw();
swapBuffers(); swapBuffers();
} }
} }
void QGLBlitter::SubWidget::resizeGL(int const w, int const h) { void SubWidget::resizeGL(int const w, int const h) {
clear_ = max_buffer_cnt; clear_ = max_buffer_cnt;
glViewport(0, 0, w, h); glViewport(0, 0, w, h);
@ -194,7 +201,7 @@ void QGLBlitter::SubWidget::resizeGL(int const w, int const h) {
glEndList(); glEndList();
} }
void QGLBlitter::SubWidget::setBilinearFiltering(bool const on) { void SubWidget::setBilinearFiltering(bool const on) {
bool const oldbf = bf_; bool const oldbf = bf_;
bf_ = on; bf_ = on;
@ -205,13 +212,13 @@ void QGLBlitter::SubWidget::setBilinearFiltering(bool const on) {
} }
} }
void QGLBlitter::SubWidget::setTextureSize(QSize const &size) { void SubWidget::setTextureSize(QSize const &size) {
inSize_ = size; inSize_ = size;
if (initialized_) if (initialized_)
glInit(); glInit();
} }
void QGLBlitter::SubWidget::present() { void SubWidget::present() {
swapBuffers(); swapBuffers();
if (swapInterval_) if (swapInterval_)
@ -221,7 +228,7 @@ void QGLBlitter::SubWidget::present() {
draw(); draw();
} }
void QGLBlitter::SubWidget::updateTexture(quint32 const *data) { void SubWidget::updateTexture(quint32 const *data) {
if (!initialized_) { if (!initialized_) {
glInit(); glInit();
} else if (QGLContext::currentContext() != context()) } else if (QGLContext::currentContext() != context())
@ -231,85 +238,137 @@ void QGLBlitter::SubWidget::updateTexture(quint32 const *data) {
inSize_.height(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); inSize_.height(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
} }
QGLBlitter::QGLBlitter(VideoBufferLocker vbl, DwmControlHwndChange hwndChange, QWidget *parent) class QGLBlitter : public BlitterWidget {
: BlitterWidget(vbl, QString("OpenGL"), 2, parent) public:
, hwndChange_(hwndChange) QGLBlitter(VideoBufferLocker vbl, DwmControlHwndChange hwndChange, QWidget *parent)
, confWidget_(new QWidget) : BlitterWidget(vbl, QString("OpenGL"), 2, parent)
, vsync_(new QCheckBox(QString("Wait for vertical blank")), "qglblitter/vsync", false) , hwndChange_(hwndChange)
, bf_(new QCheckBox(QString("Bilinear filtering")), "qglblitter/bf", true) , confWidget_(new QWidget)
, correctedSize_(size()) , vsync_(new QCheckBox(QString("Wait for vertical blank")), "qglblitter/vsync", false)
, swapInterval_(0) , bf_(new QCheckBox(QString("Bilinear filtering")), "qglblitter/bf", true)
, dhz_(600) , correctedSize_(size())
{ , swapInterval_(0)
confWidget_->setLayout(new QVBoxLayout); , dhz_(600)
confWidget_->layout()->setMargin(0); {
confWidget_->layout()->addWidget(vsync_.checkBox()); confWidget_->setLayout(new QVBoxLayout);
confWidget_->layout()->addWidget(bf_.checkBox()); confWidget_->layout()->setMargin(0);
} confWidget_->layout()->addWidget(vsync_.checkBox());
confWidget_->layout()->addWidget(bf_.checkBox());
}
QGLBlitter::~QGLBlitter() { virtual void uninit() {
} subWidget_.reset();
buffer_.reset();
}
void QGLBlitter::resizeEvent(QResizeEvent *) { virtual bool isUnusable() const { return !QGLFormat::hasOpenGL(); }
if (subWidget_)
subWidget_->setGeometry(rect());
}
void QGLBlitter::uninit() { virtual void setCorrectedGeometry(int w, int h, int correctedw, int correctedh) {
subWidget_.reset(); QRect const geo(0, 0, w, h);
buffer_.reset(); correctedSize_ = QSize(correctedw, correctedh);
} if (subWidget_)
subWidget_->setCorrectedSize(correctedSize_);
bool QGLBlitter::isUnusable() const { if (geometry() != geo) {
return !QGLFormat::hasOpenGL(); setGeometry(geo);
} } else if (subWidget_)
subWidget_->forcedResize();
}
void QGLBlitter::setBufferDimensions(unsigned const width, unsigned const height) { virtual WId hwnd() const {
buffer_.reset(std::size_t(width) * height * 2); if (subWidget_)
setPixelBuffer(buffer_, PixelBuffer::RGB32, width); return subWidget_->winId();
if (subWidget_) { return BlitterWidget::hwnd();
subWidget_->setTextureSize(QSize(width, height)); }
} else
createNewSubWidget(calcSubWidgetSwapInterval());
} virtual long frameTimeEst() const {
if (subWidget_ && subWidget_->swapInterval() && swapInterval_)
return subWidget_->frameTimeEst();
void QGLBlitter::blit() { return BlitterWidget::frameTimeEst();
setPixelBuffer(inBuffer().data == buffer_ ? buffer_ + buffer_.size() / 2 : buffer_, }
inBuffer().pixelFormat, inBuffer().pitch);
}
void QGLBlitter::draw() { virtual void blit() {
subWidget_->updateTexture(inBuffer().data == buffer_ setPixelBuffer(inBuffer().data == buffer_ ? buffer_ + buffer_.size() / 2 : buffer_,
? buffer_ + buffer_.size() / 2 inBuffer().pixelFormat, inBuffer().pitch);
: buffer_); }
subWidget_->prepare();
}
void QGLBlitter::setCorrectedGeometry(int w, int h, int correctedw, int correctedh) { virtual void draw() {
QRect const geo(0, 0, w, h); subWidget_->updateTexture(inBuffer().data == buffer_
correctedSize_ = QSize(correctedw, correctedh); ? buffer_ + buffer_.size() / 2
if (subWidget_) : buffer_);
subWidget_->setCorrectedSize(correctedSize_); subWidget_->prepare();
}
if (geometry() != geo) { virtual long sync() {
setGeometry(geo); subWidget_->present();
} else if (subWidget_) return 0;
subWidget_->forcedResize(); }
}
long QGLBlitter::frameTimeEst() const { virtual QWidget * settingsWidget() const { return confWidget_.get(); }
if (subWidget_ && subWidget_->swapInterval() && swapInterval_)
return subWidget_->frameTimeEst();
return BlitterWidget::frameTimeEst(); virtual void acceptSettings() {
} bf_.accept();
vsync_.accept();
long QGLBlitter::sync() { if (subWidget_) {
subWidget_->present(); updateSubWidgetSwapInterval();
return 0; subWidget_->setBilinearFiltering(bf_.value());
} }
}
virtual void rejectSettings() const {
vsync_.reject();
bf_.reject();
}
virtual void setSwapInterval(unsigned si) {
swapInterval_ = si;
updateSubWidgetSwapInterval();
}
virtual void rateChange(int const dhz) {
dhz_ = dhz ? dhz : 600;
if (subWidget_)
subWidget_->setRefreshRate(dhz_);
}
virtual void compositionEnabledChange() { updateSubWidgetSwapInterval(); }
protected:
virtual void setBufferDimensions(unsigned const width, unsigned const height) {
buffer_.reset(std::size_t(width) * height * 2);
setPixelBuffer(buffer_, PixelBuffer::RGB32, width);
if (subWidget_) {
subWidget_->setTextureSize(QSize(width, height));
} else
createNewSubWidget(calcSubWidgetSwapInterval());
}
virtual void resizeEvent(QResizeEvent *) {
if (subWidget_)
subWidget_->setGeometry(rect());
}
private:
DwmControlHwndChange const hwndChange_;
scoped_ptr<QWidget> const confWidget_;
PersistCheckBox vsync_;
PersistCheckBox bf_;
Array<quint32> buffer_;
QSize correctedSize_;
unsigned swapInterval_;
int dhz_;
scoped_ptr<SubWidget> subWidget_;
unsigned calcSubWidgetSwapInterval() const;
void createNewSubWidget(unsigned swapInterval);
void updateSubWidgetSwapInterval();
virtual void privSetPaused(bool ) {}
};
unsigned QGLBlitter::calcSubWidgetSwapInterval() const { unsigned QGLBlitter::calcSubWidgetSwapInterval() const {
return swapInterval_ return swapInterval_
@ -321,7 +380,7 @@ void QGLBlitter::createNewSubWidget(unsigned const swapInterval) {
subWidget_.reset(); subWidget_.reset();
subWidget_.reset(new SubWidget(correctedSize_, subWidget_.reset(new SubWidget(correctedSize_,
QSize(inBuffer().width, inBuffer().height), QSize(inBuffer().width, inBuffer().height),
swapInterval, dhz_, bf_.value(), this)); swapInterval, dhz_, bf_.value(), *this));
subWidget_->setGeometry(rect()); subWidget_->setGeometry(rect());
subWidget_->show(); subWidget_->show();
hwndChange_(this); hwndChange_(this);
@ -333,40 +392,10 @@ void QGLBlitter::updateSubWidgetSwapInterval() {
createNewSubWidget(swapInterval); createNewSubWidget(swapInterval);
} }
void QGLBlitter::acceptSettings() { } // anon ns
bf_.accept();
vsync_.accept();
if (subWidget_) { transfer_ptr<BlitterWidget> createQGLBlitter(VideoBufferLocker vbl,
updateSubWidgetSwapInterval(); DwmControlHwndChange hwndChange,
subWidget_->setBilinearFiltering(bf_.value()); QWidget *parent) {
} return transfer_ptr<BlitterWidget>(new QGLBlitter(vbl, hwndChange, parent));
}
void QGLBlitter::rejectSettings() const {
vsync_.reject();
bf_.reject();
}
void QGLBlitter::setSwapInterval(unsigned si) {
swapInterval_ = si;
updateSubWidgetSwapInterval();
}
void QGLBlitter::compositionEnabledChange() {
updateSubWidgetSwapInterval();
}
void QGLBlitter::rateChange(int const dhz) {
dhz_ = dhz ? dhz : 600;
if (subWidget_)
subWidget_->setRefreshRate(dhz_);
}
WId QGLBlitter::hwnd() const {
if (subWidget_)
return subWidget_->winId();
return BlitterWidget::hwnd();
} }

View File

@ -19,54 +19,15 @@
#ifndef QGLBLITTER_H #ifndef QGLBLITTER_H
#define QGLBLITTER_H #define QGLBLITTER_H
#include "../blitterwidget.h" #include "transfer_ptr.h"
#include "../dwmcontrol.h"
#include "array.h"
#include "persistcheckbox.h"
#include "scoped_ptr.h"
class QGLBlitter : public BlitterWidget { class BlitterWidget;
public: class DwmControlHwndChange;
QGLBlitter(VideoBufferLocker vbl, DwmControlHwndChange hwndChange, QWidget *parent = 0); class QWidget;
virtual ~QGLBlitter(); class VideoBufferLocker;
virtual void uninit();
virtual bool isUnusable() const;
virtual void setCorrectedGeometry(int w, int h, int new_w, int new_h);
virtual WId hwnd() const;
virtual long frameTimeEst() const;
virtual void blit();
virtual void draw();
virtual long sync();
virtual QWidget * settingsWidget() const { return confWidget_.get(); }
virtual void acceptSettings(); transfer_ptr<BlitterWidget> createQGLBlitter(VideoBufferLocker vbl,
virtual void rejectSettings() const; DwmControlHwndChange hwndChange,
QWidget *parent = 0);
virtual void setSwapInterval(unsigned);
virtual void rateChange(int dhz);
virtual void compositionEnabledChange();
protected:
virtual void setBufferDimensions(unsigned width, unsigned height);
virtual void resizeEvent(QResizeEvent *event);
private:
class SubWidget;
DwmControlHwndChange const hwndChange_;
scoped_ptr<QWidget> const confWidget_;
PersistCheckBox vsync_;
PersistCheckBox bf_;
Array<quint32> buffer_;
QSize correctedSize_;
unsigned swapInterval_;
int dhz_;
scoped_ptr<SubWidget> subWidget_;
unsigned calcSubWidgetSwapInterval() const;
void createNewSubWidget(unsigned swapInterval);
void updateSubWidgetSwapInterval();
virtual void privSetPaused(bool ) {}
};
#endif #endif

View File

@ -234,7 +234,7 @@ static auto_vector<BlitterWidget> makeBlitterWidgets(const VideoBufferLocker vbl
auto_vector<BlitterWidget> blitters; auto_vector<BlitterWidget> blitters;
addBlitterWidgets(blitters, vbl); addBlitterWidgets(blitters, vbl);
blitters.push_back(new QGLBlitter(vbl, hwndc)); blitters.push_back(createQGLBlitter(vbl, hwndc).release());
blitters.push_back(createQPainterBlitter(vbl).release()); blitters.push_back(createQPainterBlitter(vbl).release());
for (auto_vector<BlitterWidget>::iterator it = blitters.begin(); it != blitters.end();) { for (auto_vector<BlitterWidget>::iterator it = blitters.begin(); it != blitters.end();) {