summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2015-03-13 15:07:52 -0700
committerChris Craik <ccraik@google.com>2015-03-18 16:10:24 -0700
commite2bb380bc26749782c873e5488cfdf4e42b27346 (patch)
tree3e05a9dfe166da3649ac2f1673274785233d6912 /libs/hwui
parent8c6e4b398040ec0b52a7cc0cef54728f126e3841 (diff)
downloadframeworks_base-e2bb380bc26749782c873e5488cfdf4e42b27346.zip
frameworks_base-e2bb380bc26749782c873e5488cfdf4e42b27346.tar.gz
frameworks_base-e2bb380bc26749782c873e5488cfdf4e42b27346.tar.bz2
Use glops for text rendering
Change-Id: I5e155c8baf3149f0ff231ec3c89dbff6bb8eae92
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/FontRenderer.cpp42
-rw-r--r--libs/hwui/FontRenderer.h4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp12
-rw-r--r--libs/hwui/PathCache.cpp49
-rw-r--r--libs/hwui/PathCache.h20
-rw-r--r--libs/hwui/Texture.h2
-rw-r--r--libs/hwui/font/CacheTexture.cpp71
-rw-r--r--libs/hwui/font/CacheTexture.h47
-rw-r--r--libs/hwui/utils/Macros.h8
9 files changed, 142 insertions, 113 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index d1d2fcc..fd2bdc6 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -19,6 +19,8 @@
#include "Caches.h"
#include "Debug.h"
#include "Extensions.h"
+#include "Glop.h"
+#include "GlopBuilder.h"
#include "OpenGLRenderer.h"
#include "PixelBuffer.h"
#include "Rect.h"
@@ -44,10 +46,12 @@ namespace uirenderer {
// blur inputs smaller than this constant will bypass renderscript
#define RS_MIN_INPUT_CUTOFF 10000
+#define USE_GLOPS true
+
///////////////////////////////////////////////////////////////////////////////
// TextSetupFunctor
///////////////////////////////////////////////////////////////////////////////
-status_t TextSetupFunctor::setup(GLenum glyphFormat) {
+void TextSetupFunctor::setup(GLenum glyphFormat) {
renderer->setupDraw();
renderer->setupDrawTextGamma(paint);
renderer->setupDrawDirtyRegionsDisabled();
@@ -84,8 +88,24 @@ status_t TextSetupFunctor::setup(GLenum glyphFormat) {
renderer->setupDrawColorFilterUniforms(paint->getColorFilter());
renderer->setupDrawShaderUniforms(paint->getShader(), pureTranslate);
renderer->setupDrawTextGammaUniforms();
+}
- return NO_ERROR;
+void TextSetupFunctor::draw(CacheTexture& texture, bool linearFiltering) {
+ int textureFillFlags = static_cast<int>(texture.getFormat() == GL_ALPHA
+ ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone);
+ if (linearFiltering) {
+ textureFillFlags |= TextureFillFlags::kForceFilter;
+ }
+ const Matrix4& transform = pureTranslate ? Matrix4::identity() : *(renderer->currentTransform());
+ Glop glop;
+ GlopBuilder(renderer->mRenderState, renderer->mCaches, &glop)
+ .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
+ .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, renderer->currentSnapshot()->alpha)
+ .setTransform(renderer->currentSnapshot()->getOrthoMatrix(), transform, false)
+ .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0))
+ .setRoundRectClipState(renderer->currentSnapshot()->roundRectClipState)
+ .build();
+ renderer->renderGlop(glop);
}
///////////////////////////////////////////////////////////////////////////////
@@ -196,7 +216,7 @@ void FontRenderer::flushLargeCaches(Vector<CacheTexture*>& cacheTextures) {
while (it.next()) {
it.value()->invalidateTextureCache(cacheTexture);
}
- cacheTexture->releaseTexture();
+ cacheTexture->releasePixelBuffer();
}
}
}
@@ -290,7 +310,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
if (!cacheTexture->getPixelBuffer()) {
Caches::getInstance().textureState().activateTexture(0);
// Large-glyph texture memory is allocated only as needed
- cacheTexture->allocateTexture();
+ cacheTexture->allocatePixelBuffer();
}
if (!cacheTexture->mesh()) {
cacheTexture->allocateMesh();
@@ -402,7 +422,7 @@ CacheTexture* FontRenderer::createCacheTexture(int width, int height, GLenum for
if (allocate) {
Caches::getInstance().textureState().activateTexture(0);
- cacheTexture->allocateTexture();
+ cacheTexture->allocatePixelBuffer();
cacheTexture->allocateMesh();
}
@@ -497,9 +517,10 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
CacheTexture* texture = cacheTextures[i];
if (texture->canDraw()) {
if (first) {
+ checkTextureUpdate();
+#if !USE_GLOPS
mFunctor->setup(texture->getFormat());
- checkTextureUpdate();
renderState.meshState().bindQuadIndicesBuffer();
// If returns true, a VBO was bound and we must
@@ -508,12 +529,17 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
forceRebind = renderState.meshState().unbindMeshBuffer();
caches.textureState().activateTexture(0);
+#endif
first = false;
mDrawn = true;
}
+#if USE_GLOPS
+ mFunctor->draw(*texture, mLinearFiltering);
+#endif
+#if !USE_GLOPS
caches.textureState().bindTexture(texture->getTextureId());
- texture->setLinearFiltering(mLinearFiltering, false);
+ texture->setLinearFiltering(mLinearFiltering);
TextureVertex* mesh = texture->mesh();
MeshState& meshState = renderState.meshState();
@@ -522,7 +548,7 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
glDrawElements(GL_TRIANGLES, texture->meshElementCount(),
GL_UNSIGNED_SHORT, texture->indices());
-
+#endif
texture->resetMesh();
forceRebind = false;
}
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index cb63684..0603389 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -59,7 +59,9 @@ public:
, paint(paint) {
}
- status_t setup(GLenum glyphFormat);
+ void setup(GLenum glyphFormat);
+
+ void draw(CacheTexture& texture, bool linearFiltering);
OpenGLRenderer* renderer;
float x;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 622b570..3781969 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2935,27 +2935,27 @@ int OpenGLRenderer::save(int flags) {
}
void OpenGLRenderer::restore() {
- return mState.restore();
+ mState.restore();
}
void OpenGLRenderer::restoreToCount(int saveCount) {
- return mState.restoreToCount(saveCount);
+ mState.restoreToCount(saveCount);
}
void OpenGLRenderer::translate(float dx, float dy, float dz) {
- return mState.translate(dx, dy, dz);
+ mState.translate(dx, dy, dz);
}
void OpenGLRenderer::rotate(float degrees) {
- return mState.rotate(degrees);
+ mState.rotate(degrees);
}
void OpenGLRenderer::scale(float sx, float sy) {
- return mState.scale(sx, sy);
+ mState.scale(sx, sy);
}
void OpenGLRenderer::skew(float sx, float sy) {
- return mState.skew(sx, sy);
+ mState.skew(sx, sy);
}
void OpenGLRenderer::setMatrix(const Matrix4& matrix) {
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 5b2e5e2..2703072 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -40,25 +40,25 @@ namespace uirenderer {
// Cache entries
///////////////////////////////////////////////////////////////////////////////
-PathDescription::PathDescription():
- type(kShapeNone),
- join(SkPaint::kDefault_Join),
- cap(SkPaint::kDefault_Cap),
- style(SkPaint::kFill_Style),
- miter(4.0f),
- strokeWidth(1.0f),
- pathEffect(nullptr) {
+PathDescription::PathDescription()
+ : type(kShapeNone)
+ , join(SkPaint::kDefault_Join)
+ , cap(SkPaint::kDefault_Cap)
+ , style(SkPaint::kFill_Style)
+ , miter(4.0f)
+ , strokeWidth(1.0f)
+ , pathEffect(nullptr) {
memset(&shape, 0, sizeof(Shape));
}
-PathDescription::PathDescription(ShapeType type, const SkPaint* paint):
- type(type),
- join(paint->getStrokeJoin()),
- cap(paint->getStrokeCap()),
- style(paint->getStyle()),
- miter(paint->getStrokeMiter()),
- strokeWidth(paint->getStrokeWidth()),
- pathEffect(paint->getPathEffect()) {
+PathDescription::PathDescription(ShapeType type, const SkPaint* paint)
+ : type(type)
+ , join(paint->getStrokeJoin())
+ , cap(paint->getStrokeCap())
+ , style(paint->getStyle())
+ , miter(paint->getStrokeMiter())
+ , strokeWidth(paint->getStrokeWidth())
+ , pathEffect(paint->getPathEffect()) {
memset(&shape, 0, sizeof(Shape));
}
@@ -132,18 +132,6 @@ static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap,
canvas.drawPath(*path, pathPaint);
}
-static PathTexture* createTexture(float left, float top, float offset,
- uint32_t width, uint32_t height, uint32_t id) {
- PathTexture* texture = new PathTexture(Caches::getInstance());
- texture->left = left;
- texture->top = top;
- texture->offset = offset;
- texture->width = width;
- texture->height = height;
- texture->generation = id;
- return texture;
-}
-
///////////////////////////////////////////////////////////////////////////////
// Cache constructor/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -267,7 +255,8 @@ PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath *p
SkBitmap bitmap;
drawPath(path, paint, bitmap, left, top, offset, width, height);
- PathTexture* texture = createTexture(left, top, offset, width, height,
+ PathTexture* texture = new PathTexture(Caches::getInstance(),
+ left, top, offset, width, height,
path->getGenerationID());
generateTexture(entry, &bitmap, texture);
@@ -441,7 +430,7 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) {
if (generate) {
// It is important to specify the generation ID so we do not
// attempt to precache the same path several times
- texture = createTexture(0.0f, 0.0f, 0.0f, 0, 0, path->getGenerationID());
+ texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
sp<PathTask> task = new PathTask(path, paint, texture);
texture->setTask(task);
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 23e35cb..4297693 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -59,7 +59,19 @@ class Caches;
* Alpha texture used to represent a path.
*/
struct PathTexture: public Texture {
- PathTexture(Caches& caches): Texture(caches) {
+ PathTexture(Caches& caches, float left, float top,
+ float offset, int width, int height, int generation)
+ : Texture(caches)
+ , left(left)
+ , top(top)
+ , offset(offset) {
+ this->width = width;
+ this->height = height;
+ this->generation = generation;
+ }
+ PathTexture(Caches& caches, int generation)
+ : Texture(caches) {
+ this->generation = generation;
}
~PathTexture() {
@@ -69,15 +81,15 @@ struct PathTexture: public Texture {
/**
* Left coordinate of the path bounds.
*/
- float left;
+ float left = 0;
/**
* Top coordinate of the path bounds.
*/
- float top;
+ float top = 0;
/**
* Offset to draw the path at the correct origin.
*/
- float offset;
+ float offset = 0;
sp<Task<SkBitmap*> > task() const {
return mTask;
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index dfec462..7227ce0 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -78,7 +78,7 @@ public:
/**
* Indicates whether this texture should be cleaned up after use.
*/
- bool cleanup= false;
+ bool cleanup = false;
/**
* Optional, size of the original bitmap.
*/
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 9314126..845cf30 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -109,13 +109,17 @@ CacheBlock* CacheBlock::removeBlock(CacheBlock* head, CacheBlock* blockToRemove)
// CacheTexture
///////////////////////////////////////////////////////////////////////////////
-CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount) :
- mTexture(nullptr), mTextureId(0), mWidth(width), mHeight(height), mFormat(format),
- mLinearFiltering(false), mDirty(false), mNumGlyphs(0),
- mMesh(nullptr), mCurrentQuad(0), mMaxQuadCount(maxQuadCount),
- mCaches(Caches::getInstance()) {
+CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount)
+ : mTexture(Caches::getInstance())
+ , mFormat(format)
+ , mMaxQuadCount(maxQuadCount)
+ , mCaches(Caches::getInstance()) {
+ mTexture.width = width;
+ mTexture.height = height;
+ mTexture.blend = true;
+
mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
- mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
+ getWidth() - TEXTURE_BORDER_SIZE, getHeight() - TEXTURE_BORDER_SIZE);
// OpenGL ES 3.0+ lets us specify the row length for unpack operations such
// as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
@@ -125,7 +129,7 @@ CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint3
CacheTexture::~CacheTexture() {
releaseMesh();
- releaseTexture();
+ releasePixelBuffer();
reset();
}
@@ -144,35 +148,28 @@ void CacheTexture::init() {
// reset, then create a new remainder space to start again
reset();
mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
- mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
+ getWidth() - TEXTURE_BORDER_SIZE, getHeight() - TEXTURE_BORDER_SIZE);
}
void CacheTexture::releaseMesh() {
delete[] mMesh;
}
-void CacheTexture::releaseTexture() {
- if (mTexture) {
- delete mTexture;
- mTexture = nullptr;
+void CacheTexture::releasePixelBuffer() {
+ if (mPixelBuffer) {
+ delete mPixelBuffer;
+ mPixelBuffer = nullptr;
}
- if (mTextureId) {
- mCaches.textureState().deleteTexture(mTextureId);
- mTextureId = 0;
+ if (mTexture.id) {
+ mCaches.textureState().deleteTexture(mTexture.id);
+ mTexture.id = 0;
}
mDirty = false;
mCurrentQuad = 0;
}
-void CacheTexture::setLinearFiltering(bool linearFiltering, bool bind) {
- if (linearFiltering != mLinearFiltering) {
- mLinearFiltering = linearFiltering;
-
- const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
- if (bind) mCaches.textureState().bindTexture(getTextureId());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
- }
+void CacheTexture::setLinearFiltering(bool linearFiltering) {
+ mTexture.setFilter(linearFiltering ? GL_LINEAR : GL_NEAREST);
}
void CacheTexture::allocateMesh() {
@@ -181,18 +178,18 @@ void CacheTexture::allocateMesh() {
}
}
-void CacheTexture::allocateTexture() {
- if (!mTexture) {
- mTexture = PixelBuffer::create(mFormat, mWidth, mHeight);
+void CacheTexture::allocatePixelBuffer() {
+ if (!mPixelBuffer) {
+ mPixelBuffer = PixelBuffer::create(mFormat, getWidth(), getHeight());
}
- if (!mTextureId) {
- glGenTextures(1, &mTextureId);
+ if (!mTexture.id) {
+ glGenTextures(1, &mTexture.id);
- mCaches.textureState().bindTexture(mTextureId);
+ mCaches.textureState().bindTexture(mTexture.id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Initialize texture dimensions
- glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
+ glTexImage2D(GL_TEXTURE_2D, 0, mFormat, getWidth(), getHeight(), 0,
mFormat, GL_UNSIGNED_BYTE, nullptr);
const GLenum filtering = getLinearFiltering() ? GL_LINEAR : GL_NEAREST;
@@ -209,16 +206,16 @@ bool CacheTexture::upload() {
uint32_t x = mHasUnpackRowLength ? dirtyRect.left : 0;
uint32_t y = dirtyRect.top;
- uint32_t width = mHasUnpackRowLength ? dirtyRect.getWidth() : mWidth;
+ uint32_t width = mHasUnpackRowLength ? dirtyRect.getWidth() : getWidth();
uint32_t height = dirtyRect.getHeight();
// The unpack row length only needs to be specified when a new
// texture is bound
if (mHasUnpackRowLength) {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, mWidth);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, getWidth());
}
- mTexture->upload(x, y, width, height);
+ mPixelBuffer->upload(x, y, width, height);
setDirty(false);
return mHasUnpackRowLength;
@@ -258,7 +255,7 @@ bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_
return false;
}
- if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mHeight) {
+ if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > getHeight()) {
return false;
}
@@ -295,10 +292,10 @@ bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_
cacheBlock->mWidth -= roundedUpW;
cacheBlock->mX += roundedUpW;
- if (mHeight - glyphH >= glyphH) {
+ if (getHeight() - glyphH >= glyphH) {
// There's enough height left over to create a new CacheBlock
CacheBlock* newBlock = new CacheBlock(oldX, glyphH + TEXTURE_BORDER_SIZE,
- roundedUpW, mHeight - glyphH - TEXTURE_BORDER_SIZE);
+ roundedUpW, getHeight() - glyphH - TEXTURE_BORDER_SIZE);
#if DEBUG_FONT_RENDERER
ALOGD("fitBitmap: Created new block: this, x, y, w, h = %p, %d, %d, %d, %d",
newBlock, newBlock->mX, newBlock->mY,
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 5d3f959..6dabc76 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -17,15 +17,15 @@
#ifndef ANDROID_HWUI_CACHE_TEXTURE_H
#define ANDROID_HWUI_CACHE_TEXTURE_H
-#include <GLES3/gl3.h>
+#include "PixelBuffer.h"
+#include "Rect.h"
+#include "Texture.h"
+#include "Vertex.h"
+#include <GLES3/gl3.h>
#include <SkScalerContext.h>
-
#include <utils/Log.h>
-#include "../PixelBuffer.h"
-#include "../Rect.h"
-#include "../Vertex.h"
namespace android {
namespace uirenderer {
@@ -80,9 +80,9 @@ public:
void init();
void releaseMesh();
- void releaseTexture();
+ void releasePixelBuffer();
- void allocateTexture();
+ void allocatePixelBuffer();
void allocateMesh();
// Returns true if glPixelStorei(GL_UNPACK_ROW_LENGTH) must be reset
@@ -92,11 +92,11 @@ public:
bool fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY);
inline uint16_t getWidth() const {
- return mWidth;
+ return mTexture.width;
}
inline uint16_t getHeight() const {
- return mHeight;
+ return mTexture.height;
}
inline GLenum getFormat() const {
@@ -104,7 +104,7 @@ public:
}
inline uint32_t getOffset(uint16_t x, uint16_t y) const {
- return (y * mWidth + x) * PixelBuffer::formatSize(mFormat);
+ return (y * getWidth() + x) * PixelBuffer::formatSize(mFormat);
}
inline const Rect* getDirtyRect() const {
@@ -112,12 +112,17 @@ public:
}
inline PixelBuffer* getPixelBuffer() const {
+ return mPixelBuffer;
+ }
+
+ Texture& getTexture() {
+ allocatePixelBuffer();
return mTexture;
}
GLuint getTextureId() {
- allocateTexture();
- return mTextureId;
+ allocatePixelBuffer();
+ return mTexture.id;
}
inline bool isDirty() const {
@@ -131,7 +136,7 @@ public:
/**
* This method assumes that the proper texture unit is active.
*/
- void setLinearFiltering(bool linearFiltering, bool bind = true);
+ void setLinearFiltering(bool linearFiltering);
inline uint16_t getGlyphCount() const {
return mNumGlyphs;
@@ -176,16 +181,14 @@ public:
private:
void setDirty(bool dirty);
- PixelBuffer* mTexture;
- GLuint mTextureId;
- uint16_t mWidth;
- uint16_t mHeight;
+ PixelBuffer* mPixelBuffer = nullptr;
+ Texture mTexture;
GLenum mFormat;
- bool mLinearFiltering;
- bool mDirty;
- uint16_t mNumGlyphs;
- TextureVertex* mMesh;
- uint32_t mCurrentQuad;
+ bool mLinearFiltering = false;
+ bool mDirty = false;
+ uint16_t mNumGlyphs = 0;
+ TextureVertex* mMesh = nullptr;
+ uint32_t mCurrentQuad = 0;
uint32_t mMaxQuadCount;
Caches& mCaches;
CacheBlock* mCacheBlocks;
diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h
index 9f7ac1c..1b31059 100644
--- a/libs/hwui/utils/Macros.h
+++ b/libs/hwui/utils/Macros.h
@@ -36,8 +36,8 @@
#Type " must have standard layout")
#define MAKE_FLAGS_ENUM(enumType) \
- inline int operator|=(int lhs, enumType rhs) { \
- return lhs | static_cast<int>(rhs); \
+ inline void operator|=(int& lhs, enumType rhs) { \
+ lhs |= static_cast<int>(rhs); \
} \
inline int operator|(int lhs, enumType rhs) { \
return lhs | static_cast<int>(rhs); \
@@ -48,8 +48,8 @@
inline int operator|(enumType lhs, enumType rhs) { \
return static_cast<int>(lhs) | static_cast<int>(rhs); \
} \
- inline int operator&=(int lhs, enumType rhs) { \
- return lhs & static_cast<int>(rhs); \
+ inline void operator&=(int& lhs, enumType rhs) { \
+ lhs &= static_cast<int>(rhs); \
} \
inline int operator&(int lhs, enumType rhs) { \
return lhs & static_cast<int>(rhs); \