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/9914
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2b0a2bb..54c658d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -739,9 +739,6 @@
${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 @@
${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
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index 02f7f0f..cfed057 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -1178,7 +1178,54 @@
}
}
- 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 @@
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 @@
}
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;
}
}
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index 6cf0a59..c783b21 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -48,9 +48,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
return data;
}
- virtual void unlockInternal()
+ void unlockInternal() override
{
if(nativeBuffer) // Unlock the buffer from ANativeWindowBuffer
{
@@ -301,7 +315,7 @@
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 @@
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 @@
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 @@
{
GrallocModule::getInstance()->unlock(nativeBuffer->handle);
}
+
+ void release() override
+ {
+ Image::release();
+ }
};
#endif // __ANDROID__
diff --git a/src/OpenGL/libEGL/BUILD.gn b/src/OpenGL/libEGL/BUILD.gn
index 6286070..c9ab8ac 100644
--- a/src/OpenGL/libEGL/BUILD.gn
+++ b/src/OpenGL/libEGL/BUILD.gn
@@ -79,7 +79,6 @@
} else if (is_linux) {
sources += [
"../../Main/libX11.cpp",
- "TypeInfo.cpp",
]
ldflags =
[ "-Wl,--version-script=" + rebase_path("exports.map", root_build_dir) ]
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index b5097ac..6a5dffe 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -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 @@
}
#endif
- static Display display(nativeDisplay);
+ static DisplayImplementation display(nativeDisplay);
return &display;
}
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index 3fba9e7..ba6b92c 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -37,7 +37,9 @@
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 @@
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;
diff --git a/src/OpenGL/libEGL/EGLSurface.cpp b/src/OpenGL/libEGL/EGLSurface.cpp
index 1939431..f47cacb 100644
--- a/src/OpenGL/libEGL/EGLSurface.cpp
+++ b/src/OpenGL/libEGL/EGLSurface.cpp
@@ -38,7 +38,6 @@
namespace egl
{
-void Surface::typeinfo() {}
Surface::Surface(const Display *display, const Config *config) : display(display), config(config)
{
diff --git a/src/OpenGL/libEGL/EGLSurface.h b/src/OpenGL/libEGL/EGLSurface.h
index 3ebc2e4..c5026e2 100644
--- a/src/OpenGL/libEGL/EGLSurface.h
+++ b/src/OpenGL/libEGL/EGLSurface.h
@@ -33,8 +33,6 @@
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;
diff --git a/src/OpenGL/libEGL/TypeInfo.cpp b/src/OpenGL/libEGL/TypeInfo.cpp
deleted file mode 100644
index 370c865..0000000
--- a/src/OpenGL/libEGL/TypeInfo.cpp
+++ /dev/null
@@ -1,27 +0,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() {}
-}
diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index 0f9d3e5..cb95d0c 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -250,7 +250,7 @@
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 @@
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)
{
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index a5c86a7..d54885c 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -464,7 +464,7 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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)
{
diff --git a/src/OpenGL/libGLESv2/BUILD.gn b/src/OpenGL/libGLESv2/BUILD.gn
index 59f4f6d..e7c58f6 100644
--- a/src/OpenGL/libGLESv2/BUILD.gn
+++ b/src/OpenGL/libGLESv2/BUILD.gn
@@ -100,7 +100,6 @@
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) ]
}
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index f617835..445973b 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3241,10 +3241,11 @@
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();
}
diff --git a/src/OpenGL/libGLESv2/Device.cpp b/src/OpenGL/libGLESv2/Device.cpp
index da1583f..8b8f016 100644
--- a/src/OpenGL/libGLESv2/Device.cpp
+++ b/src/OpenGL/libGLESv2/Device.cpp
@@ -290,7 +290,7 @@
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 @@
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)
{
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 48bd363..40c8ed4 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -640,7 +640,7 @@
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 @@
}
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
{
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 @@
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)
{
diff --git a/src/OpenGL/libGLESv2/TypeInfo.cpp b/src/OpenGL/libGLESv2/TypeInfo.cpp
deleted file mode 100644
index 8fb91d3..0000000
--- a/src/OpenGL/libGLESv2/TypeInfo.cpp
+++ /dev/null
@@ -1,22 +0,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 "libEGL/Display.h"
-#include "libEGL/EGLSurface.h"
-
-namespace egl
-{
-void Surface::typeinfo() {}
-void Display::typeinfo() {}
-}
diff --git a/src/Renderer/Blitter.cpp b/src/Renderer/Blitter.cpp
index 4eea852..e10f783 100644
--- a/src/Renderer/Blitter.cpp
+++ b/src/Renderer/Blitter.cpp
@@ -39,11 +39,12 @@
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)
diff --git a/src/Renderer/Surface.cpp b/src/Renderer/Surface.cpp
index c7ca71a..f29aaae 100644
--- a/src/Renderer/Surface.cpp
+++ b/src/Renderer/Surface.cpp
@@ -41,7 +41,6 @@
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 @@
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);
diff --git a/src/Renderer/Surface.hpp b/src/Renderer/Surface.hpp
index ae37df5..16ff78c 100644
--- a/src/Renderer/Surface.hpp
+++ b/src/Renderer/Surface.hpp
@@ -250,13 +250,15 @@
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 @@
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;