/* * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "config.h" #include #include "RenderingQueue.h" #include "RQRef.h" #include #include #include #include "com_sun_webkit_graphics_WCRenderQueue.h" namespace WebCore { typedef HashMap > Addr2ByteBuffer; static Addr2ByteBuffer& getAddr2ByteBuffer() { static NeverDestroyed container; return container.get(); } /*static*/ RefPtr RenderingQueue::create( const JLObject &jRQ, int capacity, bool autoFlush) { return adoptRef(new RenderingQueue( jRQ, capacity, autoFlush)); } RenderingQueue& RenderingQueue::freeSpace(int size) { if (m_buffer && !m_buffer->hasFreeSpace(size)) { flushBuffer(); if (m_autoFlush) { flush(); } } if (!m_buffer) { m_buffer = RefPtr(ByteBuffer::create(std::max(m_capacity, size))); } return *this; } void RenderingQueue::flush() { JNIEnv* env = WebCore_GetJavaEnv(); static jmethodID midFwkFlush = env->GetMethodID( PG_GetRenderQueueClass(env), "fwkFlush", "()V"); ASSERT(midFwkFlush); env->CallVoidMethod(getWCRenderingQueue(), midFwkFlush); CheckAndClearException(env); } void RenderingQueue::disposeGraphics() { JNIEnv* env = WebCore_GetJavaEnv(); // The method is called from the dtor which potentially can be called after VM detach. // So the check for nullptr. if (!env) return; static jmethodID midFwkDisposeGraphics = env->GetMethodID( PG_GetRenderQueueClass(env), "fwkDisposeGraphics", "()V"); ASSERT(midFwkDisposeGraphics); env->CallVoidMethod(getWCRenderingQueue(), midFwkDisposeGraphics); CheckAndClearException(env); } /* * The method is called on Event thread (so, it's not concurrent with JS and the release of resources). */ RenderingQueue& RenderingQueue::flushBuffer() { if (isEmpty()) { return *this; } JNIEnv* env = WebCore_GetJavaEnv(); static jmethodID midFwkAddBuffer = env->GetMethodID(PG_GetRenderQueueClass(env), "fwkAddBuffer", "(Ljava/nio/ByteBuffer;)V"); ASSERT(midFwkAddBuffer); Addr2ByteBuffer &a2bb = getAddr2ByteBuffer(); a2bb.set(m_buffer->bufferAddress(), m_buffer); env->CallVoidMethod( getWCRenderingQueue(), midFwkAddBuffer, (jobject)(m_buffer->createDirectByteBuffer(env))); CheckAndClearException(env); m_buffer = nullptr; return *this; } } using namespace WebCore; extern "C" { JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCRenderQueue_twkRelease (JNIEnv* env, jobject, jobjectArray bufs) { /* * This method should be called on the Event thread to synchronize with JavaScript * by thread. JavaScript may access resources kept in ByteBuffer::m_refList, * so when a resource is dereferenced (as a result of ByteBuffer destruction) * it should be thread safe. */ Addr2ByteBuffer& a2bb = getAddr2ByteBuffer(); for (int i = 0; i < env->GetArrayLength(bufs); ++i) { char *key = (char *)env->GetDirectBufferAddress( JLObject(env->GetObjectArrayElement(bufs, i))); if (key != 0) { a2bb.remove(key); } } } }