summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp b/gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
new file mode 100755
index 000000000..30cc4d5ff
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
@@ -0,0 +1,135 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// EGLImageD3D.cpp: Implements the rx::EGLImageD3D class, the D3D implementation of EGL images
+
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+static gl::ImageIndex GetImageIndex(GLenum target, size_t mip, size_t layer)
+{
+ if (target == GL_TEXTURE_3D)
+ {
+ return gl::ImageIndex::Make3D(static_cast<GLint>(mip), static_cast<GLint>(layer));
+ }
+ else
+ {
+ ASSERT(layer == 0);
+ return gl::ImageIndex::MakeGeneric(target, static_cast<GLint>(mip));
+ }
+}
+
+EGLImageD3D::EGLImageD3D(RendererD3D *renderer,
+ EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs)
+ : mRenderer(renderer), mBuffer(buffer), mAttachmentBuffer(nullptr), mRenderTarget(nullptr)
+{
+ ASSERT(renderer != nullptr);
+ ASSERT(buffer != nullptr);
+
+ if (egl::IsTextureTarget(target))
+ {
+ mAttachmentBuffer = GetImplAs<TextureD3D>(GetAs<gl::Texture>(buffer));
+ mAttachmentTarget = gl::FramebufferAttachment::Target(
+ GL_NONE, GetImageIndex(egl_gl::EGLImageTargetToGLTextureTarget(target),
+ attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0),
+ attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0)));
+ }
+ else if (egl::IsRenderbufferTarget(target))
+ {
+ mAttachmentBuffer = GetImplAs<RenderbufferD3D>(GetAs<gl::Renderbuffer>(buffer));
+ mAttachmentTarget =
+ gl::FramebufferAttachment::Target(GL_NONE, gl::ImageIndex::MakeInvalid());
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+EGLImageD3D::~EGLImageD3D()
+{
+ SafeDelete(mRenderTarget);
+}
+
+egl::Error EGLImageD3D::initialize()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+gl::Error EGLImageD3D::orphan(egl::ImageSibling *sibling)
+{
+ if (sibling == mBuffer)
+ {
+ gl::Error error = copyToLocalRendertarget();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const
+{
+ if (mAttachmentBuffer)
+ {
+ FramebufferAttachmentRenderTarget *rt = nullptr;
+ gl::Error error = mAttachmentBuffer->getAttachmentRenderTarget(mAttachmentTarget, &rt);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outRT = static_cast<RenderTargetD3D *>(rt);
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ ASSERT(mRenderTarget);
+ *outRT = mRenderTarget;
+ return gl::Error(GL_NO_ERROR);
+ }
+}
+
+gl::Error EGLImageD3D::copyToLocalRendertarget()
+{
+ ASSERT(mBuffer != nullptr);
+ ASSERT(mAttachmentBuffer != nullptr);
+ ASSERT(mRenderTarget == nullptr);
+
+ RenderTargetD3D *curRenderTarget = nullptr;
+ gl::Error error = getRenderTarget(&curRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // This only currently applies do D3D11, where it invalidates FBOs with this Image attached.
+ curRenderTarget->signalDirty();
+
+ // Clear the source image buffers
+ mBuffer = nullptr;
+ mAttachmentBuffer = nullptr;
+
+ return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget);
+}
+}