Commit f41f0332 by Nicolas Capens

Avoid dummy key methods by using pure abstract classes.

Sanitizer tools desire having the vtables of any class with non-pure virtual methods, even when none of them are called in the current linkage unit. Work around this by making the affected classes pure abstract and implementing them in a derived class in the respective library responsible for creating them. Bug swiftshader:31 Change-Id: I40046f605731eb1cc3825c1ede2d8d9b5826d0f5 Reviewed-on: https://swiftshader-review.googlesource.com/9914Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 6016a144
......@@ -739,9 +739,6 @@ file(GLOB_RECURSE EGL_LIST
${OPENGL_DIR}/common/debug.h
${CMAKE_SOURCE_DIR}/include/*.h
)
# Key method definitions are only required to appease the gold linker,
# and cause vtable linking issues with other linkers.
list(REMOVE_ITEM EGL_LIST ${OPENGL_DIR}/libEGL/TypeInfo.cpp)
file(GLOB_RECURSE GL32_LIST
${OPENGL_DIR}/libGL/*.cpp
......@@ -764,9 +761,6 @@ file(GLOB_RECURSE GLES2_LIST
${CMAKE_SOURCE_DIR}/include/GLES2/*.h
${CMAKE_SOURCE_DIR}/include/GLES3/*.h
)
# Key method definitions are only required to appease the gold linker,
# and cause vtable linking issues with other linkers.
list(REMOVE_ITEM GLES2_LIST ${OPENGL_DIR}/libGLESv2/TypeInfo.cpp)
file(GLOB_RECURSE GLES_CM_LIST
${OPENGL_DIR}/libGLES_CM/*.cpp
......
......@@ -1178,7 +1178,54 @@ namespace egl
}
}
void Image::typeinfo() {}
class ImageImplementation : public Image
{
public:
ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: Image(parentTexture, width, height, format, type) {}
ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
: Image(parentTexture, width, height, depth, format, type) {}
ImageImplementation(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
: Image(width, height, format, type, pitchP) {}
ImageImplementation(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
: Image(width, height, internalFormat, multiSampleDepth, lockable) {}
~ImageImplementation() override {}
void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
{
return Image::lockInternal(x, y, z, lock, client);
}
void unlockInternal() override
{
return Image::unlockInternal();
}
void release() override
{
return Image::release();
}
};
Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
{
return new ImageImplementation(parentTexture, width, height, format, type);
}
Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
{
return new ImageImplementation(parentTexture, width, height, depth, format, type);
}
Image *Image::create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
{
return new ImageImplementation(width, height, format, type, pitchP);
}
Image *Image::create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
{
return new ImageImplementation(width, height, internalFormat, multiSampleDepth, lockable);
}
Image::~Image()
{
......@@ -1192,6 +1239,16 @@ namespace egl
ASSERT(!shared);
}
void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
{
return Surface::lockInternal(x, y, z, lock, client);
}
void Image::unlockInternal()
{
Surface::unlockInternal();
}
void Image::release()
{
int refs = dereference();
......@@ -1620,10 +1677,11 @@ namespace egl
}
else
{
sw::Surface source(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
sw::Surface *source = sw::Surface::create(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
sw::Rect sourceRect(0, 0, width, height);
sw::Rect destRect(xoffset, yoffset, xoffset + width, yoffset + height);
sw::blitter.blit(&source, sourceRect, this, destRect, false);
sw::blitter.blit(source, sourceRect, this, destRect, false);
delete source;
}
}
......
......@@ -48,9 +48,7 @@ size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei h
class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Object
{
virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
public:
protected:
// 2D texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),
......@@ -93,6 +91,19 @@ public:
Object::addRef();
}
public:
// 2D texture image
static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
// 3D texture image
static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
// Native EGL image
static Image *create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP);
// Render target
static Image *create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable);
GLsizei getWidth() const
{
return width;
......@@ -150,6 +161,9 @@ public:
unlockExternal();
}
void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override = 0;
void unlockInternal() override = 0;
struct UnpackInfo
{
UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}
......@@ -165,7 +179,7 @@ public:
void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input);
void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
void release() override;
void release() override = 0;
void unbind(const Texture *parent); // Break parent ownership and release
bool isChildOf(const Texture *parent) const;
......@@ -188,7 +202,7 @@ protected:
egl::Texture *parentTexture;
virtual ~Image();
~Image() override = 0;
void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
void loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
......@@ -252,14 +266,14 @@ public:
private:
ANativeWindowBuffer *nativeBuffer;
virtual ~AndroidNativeImage()
~AndroidNativeImage() override
{
sync(); // Wait for any threads that use this image to finish.
nativeBuffer->common.decRef(&nativeBuffer->common);
}
virtual void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
{
LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);
......@@ -289,7 +303,7 @@ private:
return data;
}
virtual void unlockInternal()
void unlockInternal() override
{
if(nativeBuffer) // Unlock the buffer from ANativeWindowBuffer
{
......@@ -301,7 +315,7 @@ private:
sw::Surface::unlockInternal();
}
virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
void *lock(unsigned int left, unsigned int top, sw::Lock lock) override
{
LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
(void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);
......@@ -309,7 +323,7 @@ private:
return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
virtual void unlock()
void unlock() override
{
LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
unlockNativeBuffer();
......@@ -318,7 +332,7 @@ private:
sw::Surface::unlockExternal();
}
void* lockNativeBuffer(int usage)
void *lockNativeBuffer(int usage)
{
void *buffer = nullptr;
GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
......@@ -330,6 +344,11 @@ private:
{
GrallocModule::getInstance()->unlock(nativeBuffer->handle);
}
void release() override
{
Image::release();
}
};
#endif // __ANDROID__
......
......@@ -79,7 +79,6 @@ shared_library("swiftshader_libEGL") {
} else if (is_linux) {
sources += [
"../../Main/libX11.cpp",
"TypeInfo.cpp",
]
ldflags =
[ "-Wl,--version-script=" + rebase_path("exports.map", root_build_dir) ]
......
......@@ -42,7 +42,18 @@
namespace egl
{
void Display::typeinfo() {}
class DisplayImplementation : public Display
{
public:
DisplayImplementation(void *nativeDisplay) : Display(nativeDisplay) {}
~DisplayImplementation() override {}
Image *getSharedImage(EGLImageKHR name) override
{
return Display::getSharedImage(name);
}
};
Display *Display::get(EGLDisplay dpy)
{
......@@ -61,7 +72,7 @@ Display *Display::get(EGLDisplay dpy)
}
#endif
static Display display(nativeDisplay);
static DisplayImplementation display(nativeDisplay);
return &display;
}
......
......@@ -37,7 +37,9 @@ namespace egl
class [[clang::lto_visibility_public]] Display
{
virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
protected:
explicit Display(void *nativeDisplay);
virtual ~Display() = 0;
public:
static Display *get(EGLDisplay dpy);
......@@ -72,12 +74,9 @@ namespace egl
EGLImageKHR createSharedImage(Image *image);
bool destroySharedImage(EGLImageKHR);
virtual Image *getSharedImage(EGLImageKHR name);
virtual Image *getSharedImage(EGLImageKHR name) = 0;
private:
explicit Display(void *nativeDisplay);
~Display();
sw::Format getDisplayFormat() const;
void *const nativeDisplay;
......
......@@ -38,7 +38,6 @@
namespace egl
{
void Surface::typeinfo() {}
Surface::Surface(const Display *display, const Config *config) : display(display), config(config)
{
......
......@@ -33,8 +33,6 @@ class Image;
class [[clang::lto_visibility_public]] Surface : public gl::Object
{
virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
public:
virtual bool initialize();
virtual void swap() = 0;
......
// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "common/Image.hpp"
#include "Main/FrameBuffer.hpp"
#include "Renderer/Surface.hpp"
namespace sw
{
void Surface::typeinfo() {}
}
namespace egl
{
void Image::typeinfo() {}
}
......@@ -250,7 +250,7 @@ namespace es1
UNREACHABLE(format);
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......@@ -269,7 +269,7 @@ namespace es1
return nullptr;
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......
......@@ -464,7 +464,7 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum form
image[level]->release();
}
image[level] = new egl::Image(this, width, height, format, type);
image[level] = egl::Image::create(this, width, height, format, type);
if(!image[level])
{
......@@ -529,7 +529,7 @@ void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
image[level]->release();
}
image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, format, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -564,7 +564,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
image[level]->release();
}
image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, format, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -714,7 +714,7 @@ void Texture2D::generateMipmaps()
image[i]->release();
}
image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......@@ -808,7 +808,7 @@ egl::Image *createBackBuffer(int width, int height, const egl::Config *config)
{
if(config)
{
return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);
return egl::Image::create(width, height, config->mRenderTargetFormat, config->mSamples, false);
}
return nullptr;
......@@ -847,7 +847,7 @@ egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Form
UNREACHABLE(format);
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......
......@@ -100,7 +100,6 @@ shared_library("swiftshader_libGLESv2") {
configs -= [ "//build/config/win:unicode" ]
ldflags = [ "/DEF:" + rebase_path("libGLESv2.def", root_build_dir) ]
} else if (is_linux) {
sources += [ "TypeInfo.cpp" ]
ldflags =
[ "-Wl,--version-script=" + rebase_path("exports.map", root_build_dir) ]
}
......
......@@ -3241,10 +3241,11 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
sw::Rect dstRect = { 0, 0, width, height };
rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
sw::Surface externalSurface(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
sw::Surface *externalSurface = sw::Surface::create(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
sw::SliceRect sliceRect(rect);
sw::SliceRect dstSliceRect(dstRect);
device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);
device->blit(renderTarget, sliceRect, externalSurface, dstSliceRect, false);
delete externalSurface;
renderTarget->release();
}
......
......@@ -290,7 +290,7 @@ namespace es2
UNREACHABLE(format);
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......@@ -309,7 +309,7 @@ namespace es2
return nullptr;
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......
......@@ -640,7 +640,7 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum form
image[level]->release();
}
image[level] = new egl::Image(this, width, height, format, type);
image[level] = egl::Image::create(this, width, height, format, type);
if(!image[level])
{
......@@ -708,7 +708,7 @@ void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -744,7 +744,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -915,7 +915,7 @@ void Texture2D::generateMipmaps()
image[i]->release();
}
image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......@@ -1137,7 +1137,7 @@ void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum forma
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[face][level])
{
......@@ -1278,7 +1278,7 @@ void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei
image[face][level]->release();
}
image[face][level] = new egl::Image(this, width, height, format, type);
image[face][level] = egl::Image::create(this, width, height, format, type);
if(!image[face][level])
{
......@@ -1306,7 +1306,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[face][level])
{
......@@ -1400,7 +1400,7 @@ void TextureCubeMap::generateMipmaps()
image[f][i]->release();
}
image[f][i] = new egl::Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
image[f][i] = egl::Image::create(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
if(!image[f][i])
{
......@@ -1601,7 +1601,7 @@ void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei dep
image[level]->release();
}
image[level] = new egl::Image(this, width, height, depth, format, type);
image[level] = egl::Image::create(this, width, height, depth, format, type);
if(!image[level])
{
......@@ -1663,7 +1663,7 @@ void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -1699,7 +1699,7 @@ void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z,
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -1877,7 +1877,7 @@ void Texture3D::generateMipmaps()
image[i]->release();
}
image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......@@ -1976,7 +1976,7 @@ void Texture2DArray::generateMipmaps()
GLsizei w = std::max(image[0]->getWidth() >> i, 1);
GLsizei h = std::max(image[0]->getHeight() >> i, 1);
image[i] = new egl::Image(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......@@ -2018,7 +2018,7 @@ egl::Image *createBackBuffer(int width, int height, const egl::Config *config)
{
if(config)
{
return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);
return egl::Image::create(width, height, config->mRenderTargetFormat, config->mSamples, false);
}
return nullptr;
......@@ -2057,7 +2057,7 @@ egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Form
UNREACHABLE(format);
}
egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
if(!surface)
{
......
// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "libEGL/Display.h"
#include "libEGL/EGLSurface.h"
namespace egl
{
void Surface::typeinfo() {}
void Display::typeinfo() {}
}
......@@ -39,11 +39,12 @@ namespace sw
return;
}
sw::Surface color(1, 1, 1, format, pixel, sw::Surface::bytes(format), sw::Surface::bytes(format));
sw::Surface *color = sw::Surface::create(1, 1, 1, format, pixel, sw::Surface::bytes(format), sw::Surface::bytes(format));
Blitter::Options clearOptions = static_cast<sw::Blitter::Options>((rgbaMask & 0xF) | CLEAR_OPERATION);
SliceRect sRect(dRect);
sRect.slice = 0;
blit(&color, sRect, dest, dRect, clearOptions);
blit(color, sRect, dest, dRect, clearOptions);
delete color;
}
bool Blitter::fastClear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
......
......@@ -41,7 +41,6 @@ namespace sw
unsigned int *Surface::palette = 0;
unsigned int Surface::paletteID = 0;
void Surface::typeinfo() {}
void Rect::clip(int minX, int minY, int maxX, int maxY)
{
......@@ -1168,6 +1167,36 @@ namespace sw
lock = LOCK_UNLOCKED;
}
class SurfaceImplementation : public Surface
{
public:
SurfaceImplementation(int width, int height, int depth, Format format, void *pixels, int pitch, int slice)
: Surface(width, height, depth, format, pixels, pitch, slice) {}
SurfaceImplementation(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0)
: Surface(texture, width, height, depth, format, lockable, renderTarget, pitchP) {}
~SurfaceImplementation() override {};
void *lockInternal(int x, int y, int z, Lock lock, Accessor client) override
{
return Surface::lockInternal(x, y, z, lock, client);
}
void unlockInternal() override
{
Surface::unlockInternal();
}
};
Surface *Surface::create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice)
{
return new SurfaceImplementation(width, height, depth, format, pixels, pitch, slice);
}
Surface *Surface::create(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchPprovided)
{
return new SurfaceImplementation(texture, width, height, depth, format, lockable, renderTarget, pitchPprovided);
}
Surface::Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice) : lockable(true), renderTarget(false)
{
resource = new Resource(0);
......
......@@ -250,13 +250,15 @@ namespace sw
bool dirty;
};
virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
public:
protected:
Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
virtual ~Surface();
public:
static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
static Surface *create(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
virtual ~Surface() = 0;
inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false);
inline void unlock(bool internal = false);
......@@ -277,8 +279,8 @@ namespace sw
inline int getExternalSliceB() const;
inline int getExternalSliceP() const;
virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client);
virtual void unlockInternal();
virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client) = 0;
virtual void unlockInternal() = 0;
inline Format getInternalFormat() const;
inline int getInternalPitchB() const;
inline int getInternalPitchP() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment