Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | // * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "GLContext.h" |
michael@0 | 7 | #include "gfx2DGlue.h" |
michael@0 | 8 | #include <ui/GraphicBuffer.h> |
michael@0 | 9 | #include "GrallocImages.h" // for GrallocImage |
michael@0 | 10 | #include "mozilla/layers/GrallocTextureHost.h" |
michael@0 | 11 | #include "mozilla/layers/CompositorOGL.h" |
michael@0 | 12 | #include "EGLImageHelpers.h" |
michael@0 | 13 | #include "GLReadTexImageHelper.h" |
michael@0 | 14 | |
michael@0 | 15 | namespace mozilla { |
michael@0 | 16 | namespace layers { |
michael@0 | 17 | |
michael@0 | 18 | using namespace android; |
michael@0 | 19 | |
michael@0 | 20 | static gfx::SurfaceFormat |
michael@0 | 21 | SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat, |
michael@0 | 22 | bool swapRB = false) |
michael@0 | 23 | { |
michael@0 | 24 | switch (aFormat) { |
michael@0 | 25 | case android::PIXEL_FORMAT_BGRA_8888: |
michael@0 | 26 | return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8; |
michael@0 | 27 | case android::PIXEL_FORMAT_RGBA_8888: |
michael@0 | 28 | return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8; |
michael@0 | 29 | case android::PIXEL_FORMAT_RGBX_8888: |
michael@0 | 30 | return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8; |
michael@0 | 31 | case android::PIXEL_FORMAT_RGB_565: |
michael@0 | 32 | return gfx::SurfaceFormat::R5G6B5; |
michael@0 | 33 | case HAL_PIXEL_FORMAT_YCbCr_422_SP: |
michael@0 | 34 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: |
michael@0 | 35 | case HAL_PIXEL_FORMAT_YCbCr_422_I: |
michael@0 | 36 | case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: |
michael@0 | 37 | case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: |
michael@0 | 38 | case HAL_PIXEL_FORMAT_YV12: |
michael@0 | 39 | return gfx::SurfaceFormat::R8G8B8A8; // yup, use SurfaceFormat::R8G8B8A8 even though it's a YUV texture. This is an external texture. |
michael@0 | 40 | default: |
michael@0 | 41 | if (aFormat >= 0x100 && aFormat <= 0x1FF) { |
michael@0 | 42 | // Reserved range for HAL specific formats. |
michael@0 | 43 | return gfx::SurfaceFormat::R8G8B8A8; |
michael@0 | 44 | } else { |
michael@0 | 45 | // This is not super-unreachable, there's a bunch of hypothetical pixel |
michael@0 | 46 | // formats we don't deal with. |
michael@0 | 47 | // We only want to abort in debug builds here, since if we crash here |
michael@0 | 48 | // we'll take down the compositor process and thus the phone. This seems |
michael@0 | 49 | // like undesirable behaviour. We'd rather have a subtle artifact. |
michael@0 | 50 | printf_stderr(" xxxxx unknow android format %i\n", (int)aFormat); |
michael@0 | 51 | MOZ_ASSERT(false, "Unknown Android pixel format."); |
michael@0 | 52 | return gfx::SurfaceFormat::UNKNOWN; |
michael@0 | 53 | } |
michael@0 | 54 | } |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | static GLenum |
michael@0 | 58 | TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat) |
michael@0 | 59 | { |
michael@0 | 60 | switch (aFormat) { |
michael@0 | 61 | case HAL_PIXEL_FORMAT_YCbCr_422_SP: |
michael@0 | 62 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: |
michael@0 | 63 | case HAL_PIXEL_FORMAT_YCbCr_422_I: |
michael@0 | 64 | case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: |
michael@0 | 65 | case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: |
michael@0 | 66 | case HAL_PIXEL_FORMAT_YV12: |
michael@0 | 67 | return LOCAL_GL_TEXTURE_EXTERNAL; |
michael@0 | 68 | case android::PIXEL_FORMAT_BGRA_8888: |
michael@0 | 69 | case android::PIXEL_FORMAT_RGBA_8888: |
michael@0 | 70 | case android::PIXEL_FORMAT_RGBX_8888: |
michael@0 | 71 | case android::PIXEL_FORMAT_RGB_565: |
michael@0 | 72 | return LOCAL_GL_TEXTURE_2D; |
michael@0 | 73 | default: |
michael@0 | 74 | if (aFormat >= 0x100 && aFormat <= 0x1FF) { |
michael@0 | 75 | // Reserved range for HAL specific formats. |
michael@0 | 76 | return LOCAL_GL_TEXTURE_EXTERNAL; |
michael@0 | 77 | } else { |
michael@0 | 78 | // This is not super-unreachable, there's a bunch of hypothetical pixel |
michael@0 | 79 | // formats we don't deal with. |
michael@0 | 80 | // We only want to abort in debug builds here, since if we crash here |
michael@0 | 81 | // we'll take down the compositor process and thus the phone. This seems |
michael@0 | 82 | // like undesirable behaviour. We'd rather have a subtle artifact. |
michael@0 | 83 | MOZ_ASSERT(false, "Unknown Android pixel format."); |
michael@0 | 84 | return LOCAL_GL_TEXTURE_EXTERNAL; |
michael@0 | 85 | } |
michael@0 | 86 | } |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor, |
michael@0 | 90 | android::GraphicBuffer* aGraphicBuffer, |
michael@0 | 91 | gfx::SurfaceFormat aFormat) |
michael@0 | 92 | : mCompositor(aCompositor) |
michael@0 | 93 | , mGraphicBuffer(aGraphicBuffer) |
michael@0 | 94 | , mEGLImage(0) |
michael@0 | 95 | , mFormat(aFormat) |
michael@0 | 96 | , mNeedsReset(true) |
michael@0 | 97 | { |
michael@0 | 98 | MOZ_ASSERT(mGraphicBuffer.get()); |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | GrallocTextureSourceOGL::~GrallocTextureSourceOGL() |
michael@0 | 102 | { |
michael@0 | 103 | DeallocateDeviceData(); |
michael@0 | 104 | mCompositor = nullptr; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | void |
michael@0 | 108 | GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) |
michael@0 | 109 | { |
michael@0 | 110 | /* |
michael@0 | 111 | * The job of this function is to ensure that the texture is tied to the |
michael@0 | 112 | * android::GraphicBuffer, so that texturing will source the GraphicBuffer. |
michael@0 | 113 | * |
michael@0 | 114 | * To this effect we create an EGLImage wrapping this GraphicBuffer, |
michael@0 | 115 | * using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our |
michael@0 | 116 | * texture using fEGLImageTargetTexture2D. |
michael@0 | 117 | */ |
michael@0 | 118 | MOZ_ASSERT(gl()); |
michael@0 | 119 | if (!IsValid()) { |
michael@0 | 120 | return; |
michael@0 | 121 | } |
michael@0 | 122 | gl()->MakeCurrent(); |
michael@0 | 123 | |
michael@0 | 124 | GLuint tex = GetGLTexture(); |
michael@0 | 125 | GLuint textureTarget = GetTextureTarget(); |
michael@0 | 126 | |
michael@0 | 127 | gl()->fActiveTexture(aTextureUnit); |
michael@0 | 128 | gl()->fBindTexture(textureTarget, tex); |
michael@0 | 129 | |
michael@0 | 130 | if (mCompositableBackendData) { |
michael@0 | 131 | // There are two paths for locking/unlocking - if mCompositableBackendData is |
michael@0 | 132 | // set, we use the texture on there, otherwise we use |
michael@0 | 133 | // CompositorBackendSpecificData from the compositor and bind the EGLImage |
michael@0 | 134 | // only in Lock(). |
michael@0 | 135 | if (!mEGLImage) { |
michael@0 | 136 | mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); |
michael@0 | 137 | } |
michael@0 | 138 | gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | ApplyFilterToBoundTexture(gl(), aFilter, textureTarget); |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | void GrallocTextureSourceOGL::Lock() |
michael@0 | 145 | { |
michael@0 | 146 | if (mCompositableBackendData) return; |
michael@0 | 147 | |
michael@0 | 148 | MOZ_ASSERT(IsValid()); |
michael@0 | 149 | |
michael@0 | 150 | mTexture = mCompositor->GetTemporaryTexture(GetTextureTarget(), LOCAL_GL_TEXTURE0); |
michael@0 | 151 | |
michael@0 | 152 | GLuint textureTarget = GetTextureTarget(); |
michael@0 | 153 | |
michael@0 | 154 | gl()->MakeCurrent(); |
michael@0 | 155 | gl()->fActiveTexture(LOCAL_GL_TEXTURE0); |
michael@0 | 156 | gl()->fBindTexture(textureTarget, mTexture); |
michael@0 | 157 | if (!mEGLImage) { |
michael@0 | 158 | mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); |
michael@0 | 159 | } |
michael@0 | 160 | gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | bool |
michael@0 | 164 | GrallocTextureSourceOGL::IsValid() const |
michael@0 | 165 | { |
michael@0 | 166 | return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mCompositableBackendData); |
michael@0 | 167 | } |
michael@0 | 168 | |
michael@0 | 169 | gl::GLContext* |
michael@0 | 170 | GrallocTextureSourceOGL::gl() const |
michael@0 | 171 | { |
michael@0 | 172 | return mCompositor ? mCompositor->gl() : nullptr; |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | void |
michael@0 | 176 | GrallocTextureSourceOGL::SetCompositor(Compositor* aCompositor) |
michael@0 | 177 | { |
michael@0 | 178 | if (mCompositor && !aCompositor) { |
michael@0 | 179 | DeallocateDeviceData(); |
michael@0 | 180 | } |
michael@0 | 181 | mCompositor = static_cast<CompositorOGL*>(aCompositor); |
michael@0 | 182 | } |
michael@0 | 183 | |
michael@0 | 184 | |
michael@0 | 185 | GLenum |
michael@0 | 186 | GrallocTextureSourceOGL::GetTextureTarget() const |
michael@0 | 187 | { |
michael@0 | 188 | MOZ_ASSERT(gl()); |
michael@0 | 189 | MOZ_ASSERT(mGraphicBuffer.get()); |
michael@0 | 190 | |
michael@0 | 191 | if (!gl() || !mGraphicBuffer.get()) { |
michael@0 | 192 | return LOCAL_GL_TEXTURE_EXTERNAL; |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | // SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will |
michael@0 | 196 | // result in black pixels when trying to draw from bound textures. |
michael@0 | 197 | // Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on |
michael@0 | 198 | // performance. |
michael@0 | 199 | // See Bug 950050. |
michael@0 | 200 | if (gl()->Renderer() == gl::GLRenderer::SGX530 || |
michael@0 | 201 | gl()->Renderer() == gl::GLRenderer::SGX540) { |
michael@0 | 202 | return LOCAL_GL_TEXTURE_EXTERNAL; |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat()); |
michael@0 | 206 | } |
michael@0 | 207 | |
michael@0 | 208 | void |
michael@0 | 209 | GrallocTextureSourceOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) |
michael@0 | 210 | { |
michael@0 | 211 | if (!aBackendData) { |
michael@0 | 212 | mCompositableBackendData = nullptr; |
michael@0 | 213 | DeallocateDeviceData(); |
michael@0 | 214 | return; |
michael@0 | 215 | } |
michael@0 | 216 | |
michael@0 | 217 | if (mCompositableBackendData != aBackendData) { |
michael@0 | 218 | mNeedsReset = true; |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | if (!mNeedsReset) { |
michael@0 | 222 | // Update binding to the EGLImage |
michael@0 | 223 | gl()->MakeCurrent(); |
michael@0 | 224 | GLuint tex = GetGLTexture(); |
michael@0 | 225 | GLuint textureTarget = GetTextureTarget(); |
michael@0 | 226 | gl()->fActiveTexture(LOCAL_GL_TEXTURE0); |
michael@0 | 227 | gl()->fBindTexture(textureTarget, tex); |
michael@0 | 228 | gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); |
michael@0 | 229 | return; |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | mCompositableBackendData = aBackendData; |
michael@0 | 233 | |
michael@0 | 234 | if (!mCompositor) { |
michael@0 | 235 | return; |
michael@0 | 236 | } |
michael@0 | 237 | |
michael@0 | 238 | // delete old EGLImage |
michael@0 | 239 | DeallocateDeviceData(); |
michael@0 | 240 | |
michael@0 | 241 | gl()->MakeCurrent(); |
michael@0 | 242 | GLuint tex = GetGLTexture(); |
michael@0 | 243 | GLuint textureTarget = GetTextureTarget(); |
michael@0 | 244 | |
michael@0 | 245 | gl()->fActiveTexture(LOCAL_GL_TEXTURE0); |
michael@0 | 246 | gl()->fBindTexture(textureTarget, tex); |
michael@0 | 247 | // create new EGLImage |
michael@0 | 248 | mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); |
michael@0 | 249 | gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage); |
michael@0 | 250 | mNeedsReset = false; |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | gfx::IntSize |
michael@0 | 254 | GrallocTextureSourceOGL::GetSize() const |
michael@0 | 255 | { |
michael@0 | 256 | if (!IsValid()) { |
michael@0 | 257 | NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL"); |
michael@0 | 258 | return gfx::IntSize(0, 0); |
michael@0 | 259 | } |
michael@0 | 260 | return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight()); |
michael@0 | 261 | } |
michael@0 | 262 | |
michael@0 | 263 | void |
michael@0 | 264 | GrallocTextureSourceOGL::DeallocateDeviceData() |
michael@0 | 265 | { |
michael@0 | 266 | if (mEGLImage) { |
michael@0 | 267 | MOZ_ASSERT(gl()); |
michael@0 | 268 | gl()->MakeCurrent(); |
michael@0 | 269 | EGLImageDestroy(gl(), mEGLImage); |
michael@0 | 270 | mEGLImage = EGL_NO_IMAGE; |
michael@0 | 271 | } |
michael@0 | 272 | } |
michael@0 | 273 | |
michael@0 | 274 | GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags, |
michael@0 | 275 | const NewSurfaceDescriptorGralloc& aDescriptor) |
michael@0 | 276 | : TextureHost(aFlags) |
michael@0 | 277 | { |
michael@0 | 278 | android::GraphicBuffer* graphicBuffer = nullptr; |
michael@0 | 279 | gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN; |
michael@0 | 280 | |
michael@0 | 281 | mSize = aDescriptor.size(); |
michael@0 | 282 | mGrallocActor = |
michael@0 | 283 | static_cast<GrallocBufferActor*>(aDescriptor.bufferParent()); |
michael@0 | 284 | |
michael@0 | 285 | if (mGrallocActor) { |
michael@0 | 286 | mGrallocActor->AddTextureHost(this); |
michael@0 | 287 | graphicBuffer = mGrallocActor->GetGraphicBuffer(); |
michael@0 | 288 | } |
michael@0 | 289 | |
michael@0 | 290 | if (graphicBuffer) { |
michael@0 | 291 | format = |
michael@0 | 292 | SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(), |
michael@0 | 293 | aFlags & TEXTURE_RB_SWAPPED); |
michael@0 | 294 | } |
michael@0 | 295 | mTextureSource = new GrallocTextureSourceOGL(nullptr, |
michael@0 | 296 | graphicBuffer, |
michael@0 | 297 | format); |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | GrallocTextureHostOGL::~GrallocTextureHostOGL() |
michael@0 | 301 | { |
michael@0 | 302 | mTextureSource = nullptr; |
michael@0 | 303 | if (mGrallocActor) { |
michael@0 | 304 | mGrallocActor->RemoveTextureHost(); |
michael@0 | 305 | mGrallocActor = nullptr; |
michael@0 | 306 | } |
michael@0 | 307 | } |
michael@0 | 308 | |
michael@0 | 309 | void |
michael@0 | 310 | GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor) |
michael@0 | 311 | { |
michael@0 | 312 | mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor)); |
michael@0 | 313 | } |
michael@0 | 314 | |
michael@0 | 315 | bool |
michael@0 | 316 | GrallocTextureHostOGL::Lock() |
michael@0 | 317 | { |
michael@0 | 318 | if (IsValid()) { |
michael@0 | 319 | mTextureSource->Lock(); |
michael@0 | 320 | return true; |
michael@0 | 321 | } |
michael@0 | 322 | return false; |
michael@0 | 323 | } |
michael@0 | 324 | |
michael@0 | 325 | void |
michael@0 | 326 | GrallocTextureHostOGL::Unlock() |
michael@0 | 327 | { |
michael@0 | 328 | // Unlock is done internally by binding the texture to another gralloc buffer |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | bool |
michael@0 | 332 | GrallocTextureHostOGL::IsValid() const |
michael@0 | 333 | { |
michael@0 | 334 | return mTextureSource->IsValid(); |
michael@0 | 335 | } |
michael@0 | 336 | |
michael@0 | 337 | gfx::SurfaceFormat |
michael@0 | 338 | GrallocTextureHostOGL::GetFormat() const |
michael@0 | 339 | { |
michael@0 | 340 | return mTextureSource->GetFormat(); |
michael@0 | 341 | } |
michael@0 | 342 | |
michael@0 | 343 | void |
michael@0 | 344 | GrallocTextureHostOGL::DeallocateSharedData() |
michael@0 | 345 | { |
michael@0 | 346 | if (mTextureSource) { |
michael@0 | 347 | mTextureSource->ForgetBuffer(); |
michael@0 | 348 | } |
michael@0 | 349 | if (mGrallocActor) { |
michael@0 | 350 | PGrallocBufferParent::Send__delete__(mGrallocActor); |
michael@0 | 351 | } |
michael@0 | 352 | } |
michael@0 | 353 | |
michael@0 | 354 | void |
michael@0 | 355 | GrallocTextureHostOGL::ForgetSharedData() |
michael@0 | 356 | { |
michael@0 | 357 | if (mTextureSource) { |
michael@0 | 358 | mTextureSource->ForgetBuffer(); |
michael@0 | 359 | } |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | void |
michael@0 | 363 | GrallocTextureHostOGL::DeallocateDeviceData() |
michael@0 | 364 | { |
michael@0 | 365 | mTextureSource->DeallocateDeviceData(); |
michael@0 | 366 | } |
michael@0 | 367 | |
michael@0 | 368 | LayerRenderState |
michael@0 | 369 | GrallocTextureHostOGL::GetRenderState() |
michael@0 | 370 | { |
michael@0 | 371 | if (IsValid()) { |
michael@0 | 372 | uint32_t flags = 0; |
michael@0 | 373 | if (mFlags & TEXTURE_NEEDS_Y_FLIP) { |
michael@0 | 374 | flags |= LAYER_RENDER_STATE_Y_FLIPPED; |
michael@0 | 375 | } |
michael@0 | 376 | if (mFlags & TEXTURE_RB_SWAPPED) { |
michael@0 | 377 | flags |= LAYER_RENDER_STATE_FORMAT_RB_SWAP; |
michael@0 | 378 | } |
michael@0 | 379 | return LayerRenderState(mTextureSource->mGraphicBuffer.get(), |
michael@0 | 380 | gfx::ThebesIntSize(mSize), |
michael@0 | 381 | flags, |
michael@0 | 382 | this); |
michael@0 | 383 | } |
michael@0 | 384 | |
michael@0 | 385 | return LayerRenderState(); |
michael@0 | 386 | } |
michael@0 | 387 | |
michael@0 | 388 | TemporaryRef<gfx::DataSourceSurface> |
michael@0 | 389 | GrallocTextureHostOGL::GetAsSurface() { |
michael@0 | 390 | return mTextureSource ? mTextureSource->GetAsSurface() |
michael@0 | 391 | : nullptr; |
michael@0 | 392 | } |
michael@0 | 393 | |
michael@0 | 394 | TemporaryRef<gfx::DataSourceSurface> |
michael@0 | 395 | GrallocTextureSourceOGL::GetAsSurface() { |
michael@0 | 396 | if (!IsValid()) { |
michael@0 | 397 | return nullptr; |
michael@0 | 398 | } |
michael@0 | 399 | gl()->MakeCurrent(); |
michael@0 | 400 | |
michael@0 | 401 | GLuint tex = GetGLTexture(); |
michael@0 | 402 | gl()->fActiveTexture(LOCAL_GL_TEXTURE0); |
michael@0 | 403 | gl()->fBindTexture(GetTextureTarget(), tex); |
michael@0 | 404 | if (!mEGLImage) { |
michael@0 | 405 | mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer()); |
michael@0 | 406 | } |
michael@0 | 407 | gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage); |
michael@0 | 408 | |
michael@0 | 409 | RefPtr<gfx::DataSourceSurface> surf = |
michael@0 | 410 | IsValid() ? ReadBackSurface(gl(), tex, false, GetFormat()) |
michael@0 | 411 | : nullptr; |
michael@0 | 412 | |
michael@0 | 413 | gl()->fActiveTexture(LOCAL_GL_TEXTURE0); |
michael@0 | 414 | return surf.forget(); |
michael@0 | 415 | } |
michael@0 | 416 | |
michael@0 | 417 | GLuint |
michael@0 | 418 | GrallocTextureSourceOGL::GetGLTexture() |
michael@0 | 419 | { |
michael@0 | 420 | if (mCompositableBackendData) { |
michael@0 | 421 | mCompositableBackendData->SetCompositor(mCompositor); |
michael@0 | 422 | return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture(); |
michael@0 | 423 | } |
michael@0 | 424 | |
michael@0 | 425 | return mTexture; |
michael@0 | 426 | } |
michael@0 | 427 | |
michael@0 | 428 | void |
michael@0 | 429 | GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) |
michael@0 | 430 | { |
michael@0 | 431 | mCompositableBackendData = aBackendData; |
michael@0 | 432 | if (mTextureSource) { |
michael@0 | 433 | mTextureSource->SetCompositableBackendSpecificData(aBackendData); |
michael@0 | 434 | } |
michael@0 | 435 | // Register this object to CompositableBackendSpecificData |
michael@0 | 436 | // as current TextureHost. |
michael@0 | 437 | if (aBackendData) { |
michael@0 | 438 | aBackendData->SetCurrentReleaseFenceTexture(this); |
michael@0 | 439 | } |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | } // namepsace layers |
michael@0 | 443 | } // namepsace mozilla |