Skip to content

Instantly share code, notes, and snippets.

@vvuk
Created October 31, 2013 15:55
Show Gist options
  • Save vvuk/7252135 to your computer and use it in GitHub Desktop.
Save vvuk/7252135 to your computer and use it in GitHub Desktop.
skia hacking
diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
index c02d319..f207459 100644
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -879,6 +879,10 @@ public:
return mUserData.Get(key);
}
+ virtual void *GetBackendData(BackendDataType aBackendDataType) {
+ return nullptr;
+ }
+
/* Within this rectangle all pixels will be opaque by the time the result of
* this DrawTarget is first used for drawing. Either by the underlying surface
* being used as an input to external drawing, or Snapshot() being called.
@@ -912,6 +916,14 @@ public:
{
MOZ_CRASH();
}
+
+ virtual void InitWithGLContextAndGrContext(GenericRefCountedBase* aGLContext,
+ GrContext* aGrContext,
+ const IntSize &aSize,
+ SurfaceFormat aFormat)
+ {
+ MOZ_CRASH();
+ }
#endif
protected:
@@ -1003,6 +1015,12 @@ public:
const IntSize &aSize,
SurfaceFormat aFormat);
+ static TemporaryRef<DrawTarget>
+ CreateDrawTargetSkiaWithGLContextAndGrContext(GenericRefCountedBase* aGLContext,
+ GrContext* aGrContext,
+ const IntSize &aSize,
+ SurfaceFormat aFormat);
+
static void
SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes);
#endif
diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp
index f83ef85..429cff7 100644
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -132,6 +132,9 @@ DrawTargetSkia::SetGlobalCacheLimits(int aCount, int aSizeInBytes)
DrawTargetSkia::DrawTargetSkia()
: mSnapshot(nullptr)
+#ifdef USE_SKIA_GPU
+ , mGrTextureID(0)
+#endif
{
}
@@ -139,6 +142,8 @@ DrawTargetSkia::~DrawTargetSkia()
{
#ifdef USE_SKIA_GPU
RemoveGLDrawTarget(this);
+
+ gfxDebug() << "~DrawTargetSkia: texture ID was %d" << mGrTextureID;
#endif
}
@@ -600,6 +605,21 @@ DrawTargetSkia::Mask(const Pattern &aSource,
mCanvas->drawPath(path, paint.mPaint);
}
+void
+DrawTargetSkia::MaskSurface(const Pattern &aSource,
+ SourceSurface *aMask,
+ Point aOffset,
+ const DrawOptions &aOptions)
+{
+ IntSize size = aMask->GetSize();
+ Rect maskRect = Rect(0.f, 0.f, Float(size.width), Float(size.height));
+
+ Rect dest = Rect(aOffset.x, aOffset.y, Float(size.width), Float(size.height));
+
+ FillRect(dest, ColorPattern(Color(1.0, 0.0, 0.0, 1.0)), aOptions);
+ /*MOZ_ASSERT(0);*/
+}
+
TemporaryRef<SourceSurface>
DrawTargetSkia::CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
@@ -729,6 +749,31 @@ DrawTargetSkia::InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLCont
}
void
+DrawTargetSkia::InitWithGLContextAndGrContext(GenericRefCountedBase* aGLContext,
+ GrContext* aGrContext,
+ const IntSize &aSize,
+ SurfaceFormat aFormat)
+{
+ mGLContext = aGLContext;
+ mGrContext = aGrContext;
+ mGrGLInterface = nullptr;
+
+ mSize = aSize;
+ mFormat = aFormat;
+
+ SkAutoTUnref<SkGpuDevice> device(new SkGpuDevice(mGrContext.get(),
+ GfxFormatToSkiaConfig(aFormat),
+ aSize.width, aSize.height,
+ 0));
+ SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
+ mCanvas = canvas.get();
+
+ mGrTextureID = (uint32_t) ((GrRenderTarget*)device->accessRenderTarget())->asTexture()->getTextureHandle();
+
+ AddGLDrawTarget(this);
+}
+
+void
DrawTargetSkia::SetCacheLimits(int aCount, int aSizeInBytes)
{
MOZ_ASSERT(mGrContext, "No GrContext!");
@@ -746,15 +791,12 @@ DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride
isOpaque = true;
}
- SkAutoTUnref<SkDevice> device(new SkDevice(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, isOpaque));
-
- SkBitmap bitmap = (SkBitmap)device->accessBitmap(true);
- bitmap.lockPixels();
- bitmap.setPixels(aData);
+ SkBitmap bitmap;
bitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
- bitmap.unlockPixels();
- bitmap.notifyPixelsChanged();
+ bitmap.setPixels(aData);
+ bitmap.setIsOpaque(isOpaque);
+ SkAutoTUnref<SkDevice> device(new SkDevice(bitmap));
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
mSize = aSize;
@@ -846,5 +888,25 @@ DrawTargetSkia::SnapshotDestroyed()
mSnapshot = nullptr;
}
+void *
+DrawTargetSkia::GetBackendData(BackendDataType aBackendDataType)
+{
+ if (aBackendDataType == BACKEND_DATA_SKIA_SKCANVAS) {
+ return mCanvas.get();
+ }
+
+#ifdef USE_SKIA_GPU
+ if (aBackendDataType == BACKEND_DATA_SKIA_GRCONTEXT) {
+ return mGrContext.get();
+ }
+
+ if (aBackendDataType == BACKEND_DATA_SKIA_GL_TEXTURE) {
+ return reinterpret_cast<void*>(mGrTextureID);
+ }
+#endif
+
+ return nullptr;
+}
+
}
}
diff --git a/gfx/2d/DrawTargetSkia.h b/gfx/2d/DrawTargetSkia.h
index 4e90f7a..5843472 100644
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -78,7 +78,7 @@ public:
virtual void MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
- const DrawOptions &aOptions = DrawOptions()) { MOZ_ASSERT(0); };
+ const DrawOptions &aOptions = DrawOptions());
virtual void PushClip(const Path *aPath);
virtual void PushClipRect(const Rect& aRect);
virtual void PopClip();
@@ -98,12 +98,19 @@ public:
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
+ virtual void *GetBackendData(BackendDataType aBackendDataType) MOZ_OVERRIDE;
+
#ifdef USE_SKIA_GPU
virtual GenericRefCountedBase* GetGLContext() const MOZ_OVERRIDE { return mGLContext; }
void InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
GrGLInterface* aGrGLInterface,
const IntSize &aSize,
SurfaceFormat aFormat) MOZ_OVERRIDE;
+ // this will *create* a new texture to render to
+ void InitWithGLContextAndGrContext(GenericRefCountedBase* aGLContext,
+ GrContext* aGrContext,
+ const IntSize &aSize,
+ SurfaceFormat aFormat) MOZ_OVERRIDE;
void SetCacheLimits(int aCount, int aSizeInBytes);
static void SetGlobalCacheLimits(int aCount, int aSizeInBytes);
@@ -132,6 +139,7 @@ private:
RefPtr<GenericRefCountedBase> mGLContext;
SkRefPtr<GrGLInterface> mGrGLInterface;
SkRefPtr<GrContext> mGrContext;
+ uint32_t mGrTextureID;
static int sTextureCacheCount;
static int sTextureCacheSizeInBytes;
diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
index 287ab3a..7ccfa70 100644
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -267,8 +267,10 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
{
RefPtr<DrawTargetSkia> newTarget;
newTarget = new DrawTargetSkia();
+ // Skia's Init here doesn't return anything
newTarget->Init(aData, aSize, aStride, aFormat);
retVal = newTarget;
+ break;
}
#endif
#ifdef XP_MACOSX
@@ -276,7 +278,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
{
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
if (newTarget->Init(aBackend, aData, aSize, aStride, aFormat))
- return newTarget;
+ retVal = newTarget;
break;
}
#endif
@@ -290,9 +292,11 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
return recordDT;
}
- gfxDebug() << "Failed to create DrawTarget, Type: " << aBackend << " Size: " << aSize;
- // Failed
- return nullptr;
+ if (!retVal) {
+ gfxDebug() << "Failed to create DrawTarget, Type: " << aBackend << " Size: " << aSize;
+ }
+
+ return retVal;
}
TemporaryRef<ScaledFont>
@@ -514,6 +518,18 @@ Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(GenericRefCountedBase
return newTarget;
}
+TemporaryRef<DrawTarget>
+Factory::CreateDrawTargetSkiaWithGLContextAndGrContext(GenericRefCountedBase* aGLContext,
+ GrContext* aGrContext,
+ const IntSize &aSize,
+ SurfaceFormat aFormat)
+{
+ DrawTargetSkia* newDrawTargetSkia = new DrawTargetSkia();
+ newDrawTargetSkia->InitWithGLContextAndGrContext(aGLContext, aGrContext, aSize, aFormat);
+ RefPtr<DrawTarget> newTarget = newDrawTargetSkia;
+ return newTarget;
+}
+
void
Factory::SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes)
{
diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h
index 89e3dcb..e2f591f 100644
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -55,6 +55,14 @@ enum BackendType
BACKEND_DIRECT2D1_1
};
+enum BackendDataType
+{
+ BACKEND_DATA_NONE = 0,
+ BACKEND_DATA_SKIA_SKCANVAS,
+ BACKEND_DATA_SKIA_GRCONTEXT,
+ BACKEND_DATA_SKIA_GL_TEXTURE
+};
+
enum FontType
{
FONT_DWRITE,
diff --git a/gfx/angle/src/libEGL/main.cpp b/gfx/angle/src/libEGL/main.cpp
index 424ec3f..8b9b3a1 100644
--- a/gfx/angle/src/libEGL/main.cpp
+++ b/gfx/angle/src/libEGL/main.cpp
@@ -12,6 +12,22 @@
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+static egl::Current *AllocCurrent()
+{
+ egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
+
+ if (current)
+ {
+ current->error = EGL_SUCCESS;
+ current->API = EGL_OPENGL_ES_API;
+ current->display = EGL_NO_DISPLAY;
+ current->drawSurface = EGL_NO_SURFACE;
+ current->readSurface = EGL_NO_SURFACE;
+ }
+
+ return current;
+}
+
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
@@ -43,17 +59,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
+ egl::Current *current = AllocCurrent();
if (current)
{
TlsSetValue(currentTLS, current);
-
- current->error = EGL_SUCCESS;
- current->API = EGL_OPENGL_ES_API;
- current->display = EGL_NO_DISPLAY;
- current->drawSurface = EGL_NO_SURFACE;
- current->readSurface = EGL_NO_SURFACE;
}
}
break;
@@ -88,9 +98,20 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
namespace egl
{
+
void setCurrentError(EGLint error)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ current = AllocCurrent();
+ if (!current)
+ {
+ return;
+ }
+
+ TlsSetValue(currentTLS, current);
+ }
current->error = error;
}
@@ -98,6 +119,10 @@ void setCurrentError(EGLint error)
EGLint getCurrentError()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ return EGL_NOT_INITIALIZED;
+ }
return current->error;
}
@@ -105,6 +130,16 @@ EGLint getCurrentError()
void setCurrentAPI(EGLenum API)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ current = AllocCurrent();
+ if (!current)
+ {
+ return;
+ }
+
+ TlsSetValue(currentTLS, current);
+ }
current->API = API;
}
@@ -112,6 +147,10 @@ void setCurrentAPI(EGLenum API)
EGLenum getCurrentAPI()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ return 0;
+ }
return current->API;
}
@@ -119,6 +158,16 @@ EGLenum getCurrentAPI()
void setCurrentDisplay(EGLDisplay dpy)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ current = AllocCurrent();
+ if (!current)
+ {
+ return;
+ }
+
+ TlsSetValue(currentTLS, current);
+ }
current->display = dpy;
}
@@ -126,6 +175,10 @@ void setCurrentDisplay(EGLDisplay dpy)
EGLDisplay getCurrentDisplay()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ return EGL_NO_DISPLAY;
+ }
return current->display;
}
@@ -133,6 +186,16 @@ EGLDisplay getCurrentDisplay()
void setCurrentDrawSurface(EGLSurface surface)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ current = AllocCurrent();
+ if (!current)
+ {
+ return;
+ }
+
+ TlsSetValue(currentTLS, current);
+ }
current->drawSurface = surface;
}
@@ -140,6 +203,10 @@ void setCurrentDrawSurface(EGLSurface surface)
EGLSurface getCurrentDrawSurface()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ return EGL_NO_SURFACE;
+ }
return current->drawSurface;
}
@@ -147,6 +214,16 @@ EGLSurface getCurrentDrawSurface()
void setCurrentReadSurface(EGLSurface surface)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ current = AllocCurrent();
+ if (!current)
+ {
+ return;
+ }
+
+ TlsSetValue(currentTLS, current);
+ }
current->readSurface = surface;
}
@@ -154,6 +231,10 @@ void setCurrentReadSurface(EGLSurface surface)
EGLSurface getCurrentReadSurface()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ {
+ return EGL_NO_SURFACE;
+ }
return current->readSurface;
}
diff --git a/gfx/angle/src/libGLESv2/main.cpp b/gfx/angle/src/libGLESv2/main.cpp
index 6d7a241..1232641 100644
--- a/gfx/angle/src/libGLESv2/main.cpp
+++ b/gfx/angle/src/libGLESv2/main.cpp
@@ -75,6 +75,14 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ // we might not have a current if we're being used on a thread
+ // that existed before this library was loaded
+ if (!current)
+ {
+ current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
+ TlsSetValue(currentTLS, current);
+ }
+
current->context = context;
current->display = display;
@@ -88,6 +96,13 @@ Context *getContext()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ // we might not have a current if we're being used on a thread
+ // that existed before this library was loaded
+ if (!current)
+ {
+ return NULL;
+ }
+
return current->context;
}
@@ -114,6 +129,13 @@ egl::Display *getDisplay()
{
Current *current = (Current*)TlsGetValue(currentTLS);
+ // we might not have a current if we're being used on a thread
+ // that existed before this library was loaded
+ if (!current)
+ {
+ return NULL;
+ }
+
return current->display;
}
diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp
index 7708fc0..68f3f4f 100644
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -457,7 +457,11 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
unsigned int version = 0;
bool parseSuccess = ParseGLVersion(this, &version);
+#ifdef DEBUG
printf_stderr("OpenGL version detected: %u\n", version);
+ printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR));
+ printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER));
+#endif
if (version >= mVersion) {
mVersion = version;
@@ -1357,6 +1361,12 @@ GLContext::QueryPixelFormat()
fGetIntegerv(LOCAL_GL_SAMPLES, &format.samples);
+ printf_stderr("[%p] QueryPixelFormat >> %d:%d:%d:%d %d:%d %d samples\n",
+ this,
+ format.red, format.green, format.blue, format.alpha,
+ format.depth, format.stencil,
+ format.samples);
+
return format;
}
diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h
index 6d7b2cd..4e8f5ea 100644
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2380,11 +2380,15 @@ public:
#endif
bool MakeCurrent(bool aForce = false) {
+ void *p = PR_GetThreadPrivate(sCurrentGLContextTLS);
+ if (!aForce && p == this)
+ return true;
+
#ifdef DEBUG
- PR_SetThreadPrivate(sCurrentGLContextTLS, this);
+ PR_SetThreadPrivate(sCurrentGLContextTLS, this);
- // XXX this assertion is disabled because it's triggering on Mac;
- // we need to figure out why and reenable it.
+ // XXX this assertion is disabled because it's triggering on Mac;
+ // we need to figure out why and reenable it.
#if 0
// IsOwningThreadCurrent is a bit of a misnomer;
// the "owning thread" is the creation thread,
diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp
index f293c28..cac2f8f 100644
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -340,7 +340,8 @@ public:
}
virtual bool IsCurrent() {
- return sWGLLib[mLibType].fGetCurrentContext() == mContext;
+ //return sWGLLib[mLibType].fGetCurrentContext() == mContext;
+ return true;
}
void SetIsDoubleBuffered(bool aIsDB) {
@@ -357,8 +358,10 @@ public:
}
virtual bool SwapBuffers() {
- if (!mIsDoubleBuffered)
+ if (!mIsDoubleBuffered) {
+ printf_stderr("@@@@@@@@@@@@@@@ SwapBuffers, not double buffered\n");
return false;
+ }
return ::SwapBuffers(mDC);
}
@@ -457,7 +460,10 @@ GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC);
- SetPixelFormat(dc, sWGLLib[libToUse].GetWindowPixelFormat(), nullptr);
+ if (!SetPixelFormat(dc, sWGLLib[libToUse].GetWindowPixelFormat(), nullptr)) {
+ NS_WARNING("SetPixelFormat failed!");
+ }
+
HGLRC context;
GLContextWGL *shareContext = GetGlobalContextWGL();
@@ -568,6 +574,8 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
HDC pbdc = wgl.fGetPbufferDC(pbuffer);
NS_ASSERTION(pbdc, "expected a dc");
+ GLContextWGL *shareContext = GetGlobalContextWGL();
+
HGLRC context;
if (wgl.HasRobustness()) {
int attribs[] = {
@@ -576,9 +584,16 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
0
};
- context = wgl.fCreateContextAttribs(pbdc, nullptr, attribs);
+ context = wgl.fCreateContextAttribs(pbdc,
+ shareContext ? shareContext->Context() : nullptr,
+ attribs);
} else {
context = wgl.fCreateContext(pbdc);
+ if (context && shareContext &&
+ !sWGLLib[aLibToUse].fShareLists(shareContext->Context(), context))
+ {
+ NS_WARNING("wglShareLists failed for pbuffer!");
+ }
}
if (!context) {
@@ -588,7 +603,7 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
SurfaceCaps dummyCaps = SurfaceCaps::Any();
nsRefPtr<GLContextWGL> glContext = new GLContextWGL(dummyCaps,
- nullptr, true,
+ shareContext, true,
pbuffer,
pbdc,
context,
diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp
index 5cc4480..9506272 100644
--- a/gfx/gl/GLContextSkia.cpp
+++ b/gfx/gl/GLContextSkia.cpp
@@ -26,8 +26,20 @@ extern "C" {
void EnsureGLContext(const GrGLInterface* i)
{
- const DrawTarget* drawTarget = reinterpret_cast<const DrawTarget*>(i->fCallbackData);
- GLContext* gl = static_cast<GLContext*>(drawTarget->GetGLContext());
+ // see gfxPlatform.cpp CreateSkiaGLTarget for what this hack is.
+ GLContext* gl;
+
+ intptr_t rawPtr = static_cast<intptr_t>(i->fCallbackData);
+ if ((rawPtr & 0x1) == 1) {
+ // it's an actual GLContext, as it always should be -- we should transition
+ // to this always
+ gl = reinterpret_cast<GLContext*>(rawPtr & ~0x1LL);
+ } else {
+ // it's a DrawTarget, we can grab the glcontext from that
+ const DrawTarget* drawTarget = reinterpret_cast<const DrawTarget*>(i->fCallbackData);
+ gl = static_cast<GLContext*>(drawTarget->GetGLContext());
+ }
+
gl->MakeCurrent();
if (!sGLContext.initialized()) {
diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp
index d580a3a..ce1d529 100644
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -155,6 +155,11 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD
break;
}
#endif
+ if (parentBackend == LAYERS_OPENGL && gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
+ printf_stderr("*********** CREATING DeprecatedTextureClientSkiaGLTexture\n");
+ result = new DeprecatedTextureClientSkiaGLTexture(GetForwarder(), GetTextureInfo());
+ break;
+ }
// fall through to TEXTURE_SHMEM
case TEXTURE_SHMEM:
result = new DeprecatedTextureClientShmem(GetForwarder(), GetTextureInfo());
diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp
index 0759b85..983ee4b 100644
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -519,6 +519,8 @@ DeprecatedTextureClientShmem::Unlock()
gfxImageSurface*
DeprecatedTextureClientShmem::LockImageSurface()
{
+ return nullptr;
+
if (!mSurfaceAsImage) {
gfxASurface* surface = GetSurface();
if (!surface) {
diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h
index 8811d50..696d7b3 100644
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -514,11 +514,15 @@ public:
return aType == TEXTURE_SHMEM || aType == TEXTURE_CONTENT || aType == TEXTURE_FALLBACK;
}
virtual gfxImageSurface* LockImageSurface() MOZ_OVERRIDE;
- virtual gfxASurface* LockSurface() MOZ_OVERRIDE { return GetSurface(); }
+ virtual gfxASurface* LockSurface() MOZ_OVERRIDE { return nullptr; }
virtual gfx::DrawTarget* LockDrawTarget();
virtual gfx::BackendType BackendType() MOZ_OVERRIDE
{
+#if 0
return gfx::BACKEND_CAIRO;
+#else
+ return gfx::BACKEND_SKIA;
+#endif
}
virtual void Unlock() MOZ_OVERRIDE;
virtual bool EnsureAllocated(gfx::IntSize aSize, gfxContentType aType) MOZ_OVERRIDE;
diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh
index 46679b7..0f39f9e 100644
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -51,6 +51,15 @@ struct SurfaceDescriptorD3D10 {
bool hasAlpha;
};
+// A direct GL texture from the global share
+// pool, for where we have GL context sharing
+struct SurfaceDescriptorSharedGLTexture {
+ uint32_t texture;
+ uint32_t format; // gfx::SurfaceFormat
+ nsIntSize size;
+ bool flipped; // y-flip?
+};
+
struct SharedTextureDescriptor {
SharedTextureShareType shareType;
SharedTextureHandle handle;
@@ -182,6 +191,7 @@ union SurfaceDescriptor {
Shmem; // XXX - deprecated
RGBImage; // XXX - deprecated
MemoryImage; // XXX - deprecated
+ SurfaceDescriptorSharedGLTexture;
null_t;
};
diff --git a/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp b/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp
index 88f73d4..3c1b965 100644
--- a/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp
@@ -72,7 +72,7 @@ ShadowLayerForwarder::PlatformGetDescriptorSurfaceImageFormat(
}
bool
-ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
+ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor *)
{
return false;
}
@@ -83,8 +83,13 @@ ShadowLayerForwarder::PlatformSyncBeforeUpdate()
}
bool
-ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor*)
+ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor *aDesc)
{
+ if (aDesc->type() == SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture) {
+ // nothing to do
+ return true;
+ }
+
return false;
}
diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp
index 55f3f13..5816e6e 100644
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -189,6 +189,8 @@ FPSState::DrawFPS(TimeStamp aNow,
}
aContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 64, 8, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, buf);
free(buf);
+
+ printf_stderr("FPS TEXTURE %d\n", mTexture);
}
mVBOs.Reset();
diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp
index b7c63d6..b310a46 100644
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -8,6 +8,7 @@
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/layers/ISurfaceAllocator.h"
#include "nsSize.h" // for nsIntSize
+#include "gfxPlatform.h"
using namespace mozilla::gl;
@@ -96,5 +97,48 @@ DeprecatedTextureClientSharedOGL::EnsureAllocated(gfx::IntSize aSize,
}
+DeprecatedTextureClientSkiaGLTexture::DeprecatedTextureClientSkiaGLTexture(CompositableForwarder* aForwarder,
+ const TextureInfo& aTextureInfo)
+ : DeprecatedTextureClient(aForwarder, aTextureInfo)
+{
+}
+
+void
+DeprecatedTextureClientSkiaGLTexture::ReleaseResources()
+{
+ if (IsSurfaceDescriptorValid(mDescriptor)) {
+ MOZ_ASSERT(mDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture);
+ mDescriptor = SurfaceDescriptor();
+ }
+
+ mDrawTarget = nullptr;
+ mSize.SizeTo(0, 0);
+}
+
+bool
+DeprecatedTextureClientSkiaGLTexture::EnsureAllocated(gfx::IntSize aSize,
+ gfxContentType aContentType)
+{
+ if (mSize == aSize && mContentType == aContentType) {
+ return true;
+ }
+
+ mFormat = aContentType == GFX_CONTENT_COLOR_ALPHA ? gfx::FORMAT_R8G8B8A8 : gfx::FORMAT_R8G8B8X8;
+ mSize = aSize;
+ mContentType = aContentType;
+
+ mDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(aSize, mFormat);
+
+ nsIntSize nsSize(mSize.width, mSize.height);
+ uint32_t tex = (uint32_t) mDrawTarget->GetBackendData(gfx::BACKEND_DATA_SKIA_GL_TEXTURE);
+
+ printf_stderr("DrawTargetSkiaGL texture client, GrTextureID: %d\n", tex);
+
+ mDescriptor = SurfaceDescriptorSharedGLTexture(tex, mFormat, nsSize, true);
+
+ return true;
+}
+
+
} // namespace
} // namespace
diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h
index f60729f..3a455bc 100644
--- a/gfx/layers/opengl/TextureClientOGL.h
+++ b/gfx/layers/opengl/TextureClientOGL.h
@@ -14,6 +14,11 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureClient.h" // for DeprecatedTextureClient, etc
+#ifdef USE_SKIA
+#include "skia/SkGraphics.h"
+#include "skia/GrContext.h"
+#endif
+
namespace mozilla {
namespace layers {
@@ -76,6 +81,31 @@ protected:
friend class CompositingFactory;
};
+class DeprecatedTextureClientSkiaGLTexture : public DeprecatedTextureClient
+{
+public:
+ DeprecatedTextureClientSkiaGLTexture(CompositableForwarder* aForwarder, const TextureInfo& aTextureInfo);
+ ~DeprecatedTextureClientSkiaGLTexture() { ReleaseResources(); }
+
+ virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE { return aType == TEXTURE_CONTENT; }
+ virtual bool EnsureAllocated(gfx::IntSize aSize, gfxContentType aType);
+ virtual void ReleaseResources();
+ virtual gfxContentType GetContentType() MOZ_OVERRIDE { return mContentType; }
+
+ virtual gfx::DrawTarget* LockDrawTarget() MOZ_OVERRIDE { return mDrawTarget.get(); }
+ virtual gfx::BackendType BackendType() MOZ_OVERRIDE { return gfx::BACKEND_SKIA; }
+
+protected:
+ gfx::IntSize mSize;
+ gfxContentType mContentType;
+ gfx::SurfaceFormat mFormat;
+
+ RefPtr<gfx::DrawTarget> mDrawTarget;
+
+ friend class CompositingFactory;
+};
+
+
// Doesn't own the surface descriptor, so we shouldn't delete it
class DeprecatedTextureClientSharedOGLExternal : public DeprecatedTextureClientSharedOGL
{
diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp
index 0d65282c..4383976 100644
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -68,6 +68,8 @@ CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
} else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorGralloc) {
result = new GrallocDeprecatedTextureHostOGL();
#endif
+ } else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture) {
+ result = new DeprecatedTextureHostOGLTexture();
} else if (aDeprecatedTextureHostFlags & TEXTURE_HOST_TILED) {
result = new TiledDeprecatedTextureHostOGL();
} else {
@@ -1351,5 +1353,59 @@ GrallocDeprecatedTextureHostOGL::GetAsSurface() {
}
#endif // MOZ_WIDGET_GONK
+void
+DeprecatedTextureHostOGLTexture::SetCompositor(Compositor* aCompositor)
+{
+ CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
+ mGL = glCompositor ? glCompositor->gl() : nullptr;
+}
+
+void
+DeprecatedTextureHostOGLTexture::UpdateImpl(const SurfaceDescriptor& aImage,
+ nsIntRegion* aRegion,
+ nsIntPoint* aOffset)
+{
+ SwapTexturesImpl(aImage, aRegion);
+}
+
+void
+DeprecatedTextureHostOGLTexture::SwapTexturesImpl(const SurfaceDescriptor& aImage,
+ nsIntRegion* aRegion)
+{
+ NS_ASSERTION(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture,
+ "Invalid descriptor");
+
+ SurfaceDescriptorSharedGLTexture desc = aImage.get_SurfaceDescriptorSharedGLTexture();
+
+ nsIntSize size = desc.size();
+ mSize = gfx::IntSize(size.width, size.height);
+ if (desc.flipped()) {
+ mFlags |= TEXTURE_NEEDS_Y_FLIP;
+ }
+
+ mFormat = (gfx::SurfaceFormat) desc.format();
+ mTextureHandle = desc.texture();
+}
+
+void
+DeprecatedTextureHostOGLTexture::BindTexture(GLenum aTextureUnit)
+{
+ mGL->fActiveTexture(aTextureUnit);
+ mGL->fBindTexture(GetTextureTarget(), mTextureHandle);
+}
+
+gfx3DMatrix
+DeprecatedTextureHostOGLTexture::GetTextureTransform()
+{
+ gfx3DMatrix m;
+ if (mFlags & TEXTURE_NEEDS_Y_FLIP)
+ {
+ m.Translate(gfxPoint3D(0.0f, 1.0f, 0.0f));
+ m.Scale(1.0f, -1.0f, 1.0f);
+ }
+
+ return m;
+}
+
} // namespace
} // namespace
diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h
index 1b327d7..ae665e1 100644
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -689,6 +689,89 @@ protected:
gl::SharedTextureShareType mShareType;
};
+class DeprecatedTextureHostOGLTexture : public DeprecatedTextureHost
+ , public TextureSourceOGL
+{
+public:
+ typedef gfxContentType ContentType;
+ typedef mozilla::gl::GLContext GLContext;
+ typedef mozilla::gl::TextureImage TextureImage;
+
+ DeprecatedTextureHostOGLTexture()
+ : mGL(nullptr)
+ , mTextureHandle(0)
+ , mWrapMode(LOCAL_GL_CLAMP_TO_EDGE)
+ {}
+
+ virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
+
+ virtual ~DeprecatedTextureHostOGLTexture()
+ {
+ }
+
+ virtual GLuint GetTextureHandle()
+ {
+ return mTextureHandle;
+ }
+
+ virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
+ {
+ return DeprecatedTextureHost::GetFormat();
+ }
+
+ virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
+
+ bool IsValid() const MOZ_OVERRIDE { return !!mTextureHandle; }
+
+ // override from DeprecatedTextureHost, we support both buffered
+ // and unbuffered operation.
+ virtual void UpdateImpl(const SurfaceDescriptor& aImage,
+ nsIntRegion* aRegion = nullptr,
+ nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
+ virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
+ nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
+
+ virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; }
+ virtual void SetWrapMode(GLenum aMode) { mWrapMode = aMode; }
+
+ virtual GLenum GetTextureTarget() const MOZ_OVERRIDE
+ {
+ return LOCAL_GL_TEXTURE_2D;
+ }
+
+ gfx::IntSize GetSize() const MOZ_OVERRIDE {
+ return mSize;
+ }
+
+ void BindTexture(GLenum activetex) MOZ_OVERRIDE;
+ void UnbindTexture() MOZ_OVERRIDE {}
+
+ GLuint GetTextureID() { return mTextureHandle; }
+ ContentType GetContentType()
+ {
+ return (mFormat == gfx::FORMAT_B8G8R8A8) ?
+ GFX_CONTENT_COLOR_ALPHA :
+ GFX_CONTENT_COLOR;
+ }
+
+ virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE;
+
+ virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+ {
+ return nullptr;
+ }
+
+#ifdef MOZ_LAYERS_HAVE_LOG
+ virtual const char* Name() { return "DeprecatedTextureHostOGLTexture"; }
+#endif
+
+protected:
+ nsRefPtr<gl::GLContext> mGL;
+ gfx::IntSize mSize;
+ GLuint mTextureHandle;
+ GLenum mWrapMode;
+};
+
class SurfaceStreamHostOGL : public DeprecatedTextureHost
, public TextureSourceOGL
{
diff --git a/gfx/skia/src/gpu/gl/GrGLShaderBuilder.cpp b/gfx/skia/src/gpu/gl/GrGLShaderBuilder.cpp
index f7ecf36..a12bbb6 100644
--- a/gfx/skia/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/gfx/skia/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -83,6 +83,8 @@ void append_swizzle(SkString* outAppend,
if (memcmp(swizzle, "rgba", 4)) {
outAppend->appendf(".%s", swizzle);
}
+
+ //outAppend->appendf(".rbga");
}
}
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
index 3656df9..a12964e 100644
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -56,6 +56,7 @@
#include "nsCRT.h"
#include "GLContext.h"
#include "GLContextProvider.h"
+#include "GLContextSkia.h"
#ifdef MOZ_WIDGET_ANDROID
#include "TexturePoolOGL.h"
@@ -64,6 +65,7 @@
#ifdef USE_SKIA
#include "mozilla/Hal.h"
#include "skia/SkGraphics.h"
+#include "skia/GrContext.h"
#endif
#include "mozilla/Preferences.h"
@@ -583,7 +585,31 @@ cairo_user_data_key_t kDrawTarget;
RefPtr<DrawTarget>
gfxPlatform::CreateDrawTargetForSurface(gfxASurface *aSurface, const IntSize& aSize)
{
- RefPtr<DrawTarget> drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize);
+ RefPtr<DrawTarget> drawTarget;
+ if (aSurface->GetType() == gfxSurfaceTypeImage) {
+ // go skia!
+ gfxImageSurface *is = (gfxImageSurface*) aSurface;
+ SurfaceFormat format;
+ switch (is->Format()) {
+ case gfxImageFormatARGB32: format = FORMAT_B8G8R8A8; break;
+ case gfxImageFormatRGB24: format = FORMAT_B8G8R8X8; break;
+ case gfxImageFormatA8: format = FORMAT_A8; break;
+ case gfxImageFormatRGB16_565: format = FORMAT_R5G6B5; break;
+ default: format = FORMAT_UNKNOWN;
+ }
+
+ if (format != FORMAT_UNKNOWN) {
+ drawTarget = Factory::CreateDrawTargetForData(BACKEND_SKIA,
+ is->Data(),
+ IntSize(is->Width(), is->Height()),
+ is->Stride(),
+ format);
+ }
+ }
+
+ if (!drawTarget) {
+ drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize);
+ }
aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
return drawTarget;
}
@@ -821,8 +847,11 @@ gfxPlatform::SupportsAzureContentForDrawTarget(DrawTarget* aTarget)
bool
gfxPlatform::UseAcceleratedSkiaCanvas()
{
- return Preferences::GetBool("gfx.canvas.azure.accelerated", false) &&
- mPreferredCanvasBackend == BACKEND_SKIA;
+ static int acceleratedAzure = -1;
+ if (acceleratedAzure == -1) {
+ acceleratedAzure = Preferences::GetBool("gfx.canvas.azure.accelerated", false) ? 1 : 0;
+ }
+ return acceleratedAzure && mPreferredCanvasBackend == BACKEND_SKIA;
}
void
@@ -897,6 +926,50 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
return surf.forget();
}
+static nsRefPtr<mozilla::gl::GLContext> skiaContentGLContext;
+static SkRefPtr<GrGLInterface> skiaContentGrGLInterface;
+static SkRefPtr<GrContext> skiaContentGrContext;
+
+static RefPtr<DrawTarget>
+CreateSkiaGLTarget(const IntSize& aSize, SurfaceFormat aFormat)
+{
+ nsRefPtr<LayerManager> layerManager = nullptr;
+ static int preferEGL = -1;
+
+ // uhh, I really want to know if we have a layerManager here, so that I can
+ // get the ISurfaceAllocator from the ShadowForwarder for Gonk
+
+ if (!skiaContentGLContext) {
+ if (preferEGL == -1) {
+ preferEGL = PR_GetEnv("MOZ_LAYERS_PREFER_EGL") != nullptr ? 1 : 0;
+ }
+
+ if (preferEGL) {
+ skiaContentGLContext = mozilla::gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(16, 16),
+ SurfaceCaps::ForRGBA());
+ } else {
+ skiaContentGLContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16),
+ SurfaceCaps::ForRGBA());
+ }
+
+ if (!skiaContentGLContext) {
+ return nullptr;
+ }
+
+ skiaContentGrGLInterface = CreateGrGLInterfaceFromGLContext(skiaContentGLContext);
+
+ intptr_t p = reinterpret_cast<intptr_t>(skiaContentGLContext.get());
+ p |= 1; // XXX HACK ! we need a flag. tagged pointers are back in vogue.
+ skiaContentGrGLInterface->fCallbackData = (GrGLInterfaceCallbackData) p;
+ skiaContentGrContext = GrContext::Create
+ (kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(skiaContentGrGLInterface.get()));
+ }
+
+ return Factory::CreateDrawTargetSkiaWithGLContextAndGrContext(skiaContentGLContext,
+ skiaContentGrContext.get(),
+ aSize, aFormat);
+}
+
RefPtr<DrawTarget>
gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
{
@@ -916,9 +989,15 @@ gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSi
}
return CreateDrawTargetForSurface(surf, aSize);
- } else {
- return Factory::CreateDrawTarget(aBackend, aSize, aFormat);
}
+
+ if (aBackend == BACKEND_SKIA && UseAcceleratedSkiaCanvas()) {
+ printf_stderr(">>>>>>>> Creating SkiaGL draw target\n");
+ return CreateSkiaGLTarget(aSize, aFormat);
+ }
+
+ printf_stderr(">>>>>>>> Creating NON SKIA GL target\n");
+ return Factory::CreateDrawTarget(aBackend, aSize, aFormat);
}
RefPtr<DrawTarget>
diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp
index 5e85d10..3af4fe6 100644
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -513,6 +513,7 @@ gfxWindowsPlatform::UpdateRenderMode()
contentMask |= 1 << BACKEND_DIRECT2D;
} else {
canvasMask |= 1 << BACKEND_SKIA;
+ contentMask |= 1 << BACKEND_SKIA;
}
InitBackendPrefs(canvasMask, contentMask);
}
@@ -1531,6 +1532,26 @@ gfxWindowsPlatform::IsOptimus()
return GetModuleHandleA("nvumdshim.dll");
}
+int
+gfxWindowsPlatform::GetScreenDepth() const
+{
+ // if the system doesn't have all displays with the same
+ // pixel format, just return 24 and move on with life.
+ if (!GetSystemMetrics(SM_SAMEDISPLAYFORMAT))
+ return 24;
+
+ HDC hdc = GetDC(nullptr);
+ if (!hdc)
+ return 24;
+
+ int depth = GetDeviceCaps(hdc, BITSPIXEL) *
+ GetDeviceCaps(hdc, PLANES);
+
+ ReleaseDC(nullptr, hdc);
+
+ return depth;
+}
+
IDXGIAdapter1*
gfxWindowsPlatform::GetDXGIAdapter()
{
diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h
index 9037586..fb27191 100644
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -153,6 +153,8 @@ public:
RENDER_MODE_MAX
};
+ int GetScreenDepth() const;
+
RenderMode GetRenderMode() { return mRenderMode; }
void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment