summaryrefslogtreecommitdiff
path: root/src/mbgl/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r--src/mbgl/gl/context.cpp12
-rw-r--r--src/mbgl/gl/context.hpp7
-rw-r--r--src/mbgl/gl/offscreen_texture.cpp87
-rw-r--r--src/mbgl/gl/offscreen_texture.hpp26
4 files changed, 132 insertions, 0 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index f4e565c766..d33ae067f6 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -6,6 +6,7 @@
#include <mbgl/gl/renderbuffer_resource.hpp>
#include <mbgl/gl/draw_scope_resource.hpp>
#include <mbgl/gl/texture.hpp>
+#include <mbgl/gl/offscreen_texture.hpp>
#include <mbgl/gl/command_encoder.hpp>
#include <mbgl/gl/debugging_extension.hpp>
#include <mbgl/gl/vertex_array_extension.hpp>
@@ -553,6 +554,17 @@ void Context::updateTextureResourceSub(gfx::TextureResource& resource,
Enum<gfx::TextureChannelDataType>::to(type), data));
}
+std::unique_ptr<gfx::OffscreenTexture>
+Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) {
+ return std::make_unique<gl::OffscreenTexture>(*this, size, type);
+}
+
+std::unique_ptr<gfx::OffscreenTexture>
+Context::createOffscreenTexture(const Size size,
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth,
+ gfx::TextureChannelDataType type) {
+ return std::make_unique<gl::OffscreenTexture>(*this, size, depth, type);
+}
std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() {
return std::make_unique<gl::DrawScopeResource>(createVertexArray());
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 530ff1c73f..2fb1d242ce 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -201,6 +201,13 @@ private:
void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
+ std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(
+ Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override;
+ std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(
+ Size,
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&,
+ gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override;
+
std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override;
std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override;
diff --git a/src/mbgl/gl/offscreen_texture.cpp b/src/mbgl/gl/offscreen_texture.cpp
new file mode 100644
index 0000000000..96d8b7e4c4
--- /dev/null
+++ b/src/mbgl/gl/offscreen_texture.cpp
@@ -0,0 +1,87 @@
+#include <mbgl/gl/offscreen_texture.hpp>
+#include <mbgl/gl/renderable_resource.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/framebuffer.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class OffscreenTextureResource final : public gl::RenderableResource {
+public:
+ OffscreenTextureResource(gl::Context& context_,
+ const Size size_,
+ const gfx::TextureChannelDataType type_)
+ : context(context_), size(size_), type(type_) {
+ assert(!size.isEmpty());
+ }
+
+ OffscreenTextureResource(gl::Context& context_,
+ const Size size_,
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth_,
+ const gfx::TextureChannelDataType type_)
+ : context(context_), size(size_), depth(&depth_), type(type_) {
+ assert(!size.isEmpty());
+ }
+
+ void bind() override {
+ if (!framebuffer) {
+ texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type);
+ if (depth) {
+ framebuffer = context.createFramebuffer(*texture, *depth);
+ } else {
+ framebuffer = context.createFramebuffer(*texture);
+ }
+ } else {
+ context.bindFramebuffer = framebuffer->framebuffer;
+ }
+
+ context.activeTextureUnit = 0;
+ context.scissorTest = false;
+ context.viewport = { 0, 0, size };
+ }
+
+ PremultipliedImage readStillImage() {
+ assert(framebuffer);
+ context.bindFramebuffer = framebuffer->framebuffer;
+ return context.readFramebuffer<PremultipliedImage>(size);
+ }
+
+ gfx::Texture& getTexture() {
+ assert(texture);
+ return *texture;
+ }
+
+private:
+ gl::Context& context;
+ const Size size;
+ optional<gfx::Texture> texture;
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>* depth = nullptr;
+ const gfx::TextureChannelDataType type;
+ optional<gl::Framebuffer> framebuffer;
+};
+
+OffscreenTexture::OffscreenTexture(gl::Context& context,
+ const Size size_,
+ const gfx::TextureChannelDataType type)
+ : gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type)) {
+}
+
+OffscreenTexture::OffscreenTexture(
+ gl::Context& context,
+ const Size size_,
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& renderbuffer,
+ const gfx::TextureChannelDataType type)
+ : gfx::OffscreenTexture(
+ size, std::make_unique<OffscreenTextureResource>(context, size_, renderbuffer, type)) {
+}
+
+PremultipliedImage OffscreenTexture::readStillImage() {
+ return getResource<OffscreenTextureResource>().readStillImage();
+}
+
+gfx::Texture& OffscreenTexture::getTexture() {
+ return getResource<OffscreenTextureResource>().getTexture();
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/offscreen_texture.hpp b/src/mbgl/gl/offscreen_texture.hpp
new file mode 100644
index 0000000000..5b211df505
--- /dev/null
+++ b/src/mbgl/gl/offscreen_texture.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/gfx/offscreen_texture.hpp>
+#include <mbgl/gfx/renderbuffer.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Context;
+
+class OffscreenTexture final : public gfx::OffscreenTexture {
+public:
+ OffscreenTexture(gl::Context&,
+ Size size,
+ gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte);
+ OffscreenTexture(gl::Context&,
+ Size size,
+ gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&,
+ gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte);
+
+ PremultipliedImage readStillImage() override;
+ gfx::Texture& getTexture() override;
+};
+
+} // namespace gl
+} // namespace mbgl