TINYGL: Cache and clip dirty rect on all DrawCall subclasses.

getDirtyRegion will be called twice on each DrawCall instance, so make
repeated work as short as possible.
This commit is contained in:
Vincent Pelletier 2016-07-23 17:40:41 +02:00
parent 6a63f544f0
commit bf319b5437
5 changed files with 27 additions and 21 deletions

View File

@ -72,6 +72,7 @@ void glInit(void *zbuffer1, int textureSize) {
c->fb->_textureSize = c->_textureSize = textureSize;
c->fb->_textureSizeMask = (textureSize - 1) << ZB_POINT_ST_FRAC_BITS;
c->renderRect = Common::Rect(0, 0, zbuffer->xsize, zbuffer->ysize);
// allocate GLVertex array
c->vertex_max = POLYGON_MAX_VERTEX;

View File

@ -733,7 +733,7 @@ void tglBlitSetScissorRect(const Common::Rect &rect) {
void tglBlitResetScissorRect(void) {
TinyGL::GLContext *c = TinyGL::gl_get_context();
c->_scissorRect = Common::Rect(0, 0, c->fb->xsize, c->fb->ysize);
c->_scissorRect = c->renderRect;
}
} // end of namespace Internal

View File

@ -175,8 +175,6 @@ static void tglPresentBufferDirtyRects(TinyGL::GLContext *c) {
}
} while(restartMerge);
Common::Rect renderRect(0, 0, c->fb->xsize - 1, c->fb->ysize - 1);
for (RectangleIterator it1 = rectangles.begin(); it1 != rectangles.end(); ++it1) {
RectangleIterator it2 = it1;
it2++;
@ -187,7 +185,6 @@ static void tglPresentBufferDirtyRects(TinyGL::GLContext *c) {
++it2;
}
}
(*it1).rectangle.clip(renderRect);
}
if (!rectangles.empty()) {
@ -492,10 +489,6 @@ void RasterizationDrawCall::execute(const Common::Rect &clippingRectangle, bool
c->fb->resetScissorRectangle();
}
const Common::Rect RasterizationDrawCall::getDirtyRegion() const {
return _dirtyRegion;
}
bool RasterizationDrawCall::operator==(const RasterizationDrawCall &other) const {
if (_vertexCount == other._vertexCount &&
_drawTriangleFront == other._drawTriangleFront &&
@ -515,6 +508,9 @@ BlittingDrawCall::BlittingDrawCall(Graphics::BlitImage *image, const BlitTransfo
tglIncBlitImageRef(image);
_blitState = captureState();
_imageVersion = tglGetBlitImageVersion(image);
if (TinyGL::gl_get_context()->_enableDirtyRectangles) {
computeDirtyRegion();
}
}
BlittingDrawCall::~BlittingDrawCall() {
@ -576,7 +572,7 @@ void BlittingDrawCall::applyState(const BlittingState &state) const {
c->fb->enableDepthTest(state.depthTestEnabled);
}
const Common::Rect BlittingDrawCall::getDirtyRegion() const {
void BlittingDrawCall::computeDirtyRegion() {
int blitWidth = _transform._destinationRectangle.width();
int blitHeight = _transform._destinationRectangle.height();
if (blitWidth == 0) {
@ -593,7 +589,17 @@ const Common::Rect BlittingDrawCall::getDirtyRegion() const {
tglGetBlitImageSize(_image, blitWidth, blitHeight);
}
}
return Common::Rect(_transform._destinationRectangle.left, _transform._destinationRectangle.top, _transform._destinationRectangle.left + blitWidth + 1, _transform._destinationRectangle.top + blitHeight + 1);
if (blitWidth == 0 || blitHeight == 0) {
_dirtyRegion = Common::Rect();
} else {
_dirtyRegion = Common::Rect(
_transform._destinationRectangle.left,
_transform._destinationRectangle.top,
_transform._destinationRectangle.left + blitWidth + 1,
_transform._destinationRectangle.top + blitHeight + 1
);
_dirtyRegion.clip(TinyGL::gl_get_context()->renderRect);
}
}
bool BlittingDrawCall::operator==(const BlittingDrawCall &other) const {
@ -606,6 +612,10 @@ bool BlittingDrawCall::operator==(const BlittingDrawCall &other) const {
ClearBufferDrawCall::ClearBufferDrawCall(bool clearZBuffer, int zValue, bool clearColorBuffer, int rValue, int gValue, int bValue)
: _clearZBuffer(clearZBuffer), _clearColorBuffer(clearColorBuffer), _zValue(zValue), _rValue(rValue), _gValue(gValue), _bValue(bValue), DrawCall(DrawCall_Clear) {
TinyGL::GLContext *c = TinyGL::gl_get_context();
if (c->_enableDirtyRectangles) {
_dirtyRegion = c->renderRect;
}
}
void ClearBufferDrawCall::execute(bool restoreState) const {
@ -619,11 +629,6 @@ void ClearBufferDrawCall::execute(const Common::Rect &clippingRectangle, bool re
c->fb->clearRegion(clearRect.left, clearRect.top, clearRect.width(), clearRect.height(), _clearZBuffer, _zValue, _clearColorBuffer, _rValue, _gValue, _bValue);
}
const Common::Rect ClearBufferDrawCall::getDirtyRegion() const {
TinyGL::GLContext *c = TinyGL::gl_get_context();
return Common::Rect(0, 0, c->fb->xsize, c->fb->ysize);
}
bool ClearBufferDrawCall::operator==(const ClearBufferDrawCall &other) const {
return _clearZBuffer == other._clearZBuffer &&
_clearColorBuffer == other._clearColorBuffer &&

View File

@ -63,7 +63,9 @@ public:
virtual void execute(bool restoreState) const = 0;
virtual void execute(const Common::Rect &clippingRectangle, bool restoreState) const = 0;
DrawCallType getType() const { return _type; }
virtual const Common::Rect getDirtyRegion() const = 0;
virtual const Common::Rect getDirtyRegion() const { return _dirtyRegion; }
protected:
Common::Rect _dirtyRegion;
private:
DrawCallType _type;
};
@ -75,7 +77,6 @@ public:
bool operator==(const ClearBufferDrawCall &other) const;
virtual void execute(bool restoreState) const;
virtual void execute(const Common::Rect &clippingRectangle, bool restoreState) const;
virtual const Common::Rect getDirtyRegion() const;
void *operator new(size_t size) {
return ::Internal::allocateFrame(size);
@ -95,7 +96,6 @@ public:
bool operator==(const RasterizationDrawCall &other) const;
virtual void execute(bool restoreState) const;
virtual void execute(const Common::Rect &clippingRectangle, bool restoreState) const;
virtual const Common::Rect getDirtyRegion() const;
void *operator new(size_t size) {
return ::Internal::allocateFrame(size);
@ -103,9 +103,8 @@ public:
void operator delete(void *p) { }
private:
typedef void (*gl_draw_triangle_func_ptr)(TinyGL::GLContext *c, TinyGL::GLVertex *p0, TinyGL::GLVertex *p1, TinyGL::GLVertex *p2);
void computeDirtyRegion();
Common::Rect _dirtyRegion;
typedef void (*gl_draw_triangle_func_ptr)(TinyGL::GLContext *c, TinyGL::GLVertex *p0, TinyGL::GLVertex *p1, TinyGL::GLVertex *p2);
int _vertexCount;
TinyGL::GLVertex *_vertex;
gl_draw_triangle_func_ptr _drawTriangleFront, _drawTriangleBack;
@ -160,7 +159,6 @@ public:
bool operator==(const BlittingDrawCall &other) const;
virtual void execute(bool restoreState) const;
virtual void execute(const Common::Rect &clippingRectangle, bool restoreState) const;
virtual const Common::Rect getDirtyRegion() const;
BlittingMode getBlittingMode() const { return _mode; }
@ -170,6 +168,7 @@ public:
void operator delete(void *p) { }
private:
void computeDirtyRegion();
BlitImage *_image;
BlitTransform _transform;
BlittingMode _mode;

View File

@ -256,6 +256,7 @@ typedef void (*gl_draw_triangle_func)(GLContext *c, GLVertex *p0, GLVertex *p1,
struct GLContext {
// Z buffer
FrameBuffer *fb;
Common::Rect renderRect;
// Internal texture size
int _textureSize;