bool RenderSurfaceChromium::prepareContentsTexture()
{
    IntSize requiredSize(m_contentRect.size());
    TextureManager* textureManager = layerRenderer()->textureManager();

    if (!m_contentsTexture)
        m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager);

    if (m_contentsTexture->isReserved())
        return true;

    if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) {
        m_skipsDraw = true;
        return false;
    }

    m_skipsDraw = false;
    return true;
}
示例#2
0
/*
 * socket_callback()
 *
 * this is the proc handler we register with our invisible window for hooking the
 * socket notification messages.
 *
 * returns:   boolean value representing success or failure.
 */
BOOL CALLBACK socket_callback(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam) {
   if (message == SOCKET_MSG) {
      if (WSAGETSELECTERROR(lparam)) {
         msg(PLUGIN_NAME": connection to server severed at WSAGETSELECTERROR %d.\n", WSAGetLastError());
         cleanup(true);
         return FALSE;
      }
      switch(WSAGETSELECTEVENT(lparam)) {
         case FD_READ:   //receiving data.
            //msg(PLUGIN_NAME": receiving data.\n");
            if (dispatch) {
               static Buffer b;
               char buf[2048];  //read a large chunk, we'll be notified if there is more
               int len = recv(conn, buf, sizeof(buf), 0);
               //connection closed.
               if (len <= 0) {
                  cleanup();
                  msg(PLUGIN_NAME": Socket read failed. connection closed. %d\n", WSAGetLastError());
                  return false;
               }
               //msg(PLUGIN_NAME": received: %d bytes \n", len);
               b.write(buf, len);   //copy new data into static buffer
               //now dispatch any complete data packets to user dispatcher
               //it is important to understand that the recv above may receive 
               //partial data packets
               //if (isComplete(b)) {
               //      msg(PLUGIN_NAME": b is complete.\n");
               //}
               //else {
               //      msg(PLUGIN_NAME": b is not compelete.\n");
               //}
               while (isComplete(b)) {
                  Buffer data(b.get_buf() + sizeof(int), requiredSize(b) - sizeof(int));
                  //msg("dispatching a %d sized buffer (expected %d out of %d)\n", data.size(), requiredSize(b) - sizeof(int), b.size());
                  if (!(*dispatch)(data)) {  //not sure we really care what is returned here
                     msg(PLUGIN_NAME": connection to server severed at dispatch.\n");
                     cleanup(true);
                     break;
                  }
                  else {
                     //msg(PLUGIN_NAME": dispatch routine called successfully.\n");
                  }
                  shift(b);  //shift any remaining portions of the buffer to the front
               }
            }
            break;
         case FD_WRITE: {   //sending data.
            //msg(PLUGIN_NAME": writing data.\n");
            if (sendBuf.size() == 0) break;  //nothing to send
            int len = send(conn, (const char*)sendBuf.get_buf(), sendBuf.size(), 0);
            //remember, send is not guaranteed to send complete buffer
            if (len == SOCKET_ERROR) {
               int error = WSAGetLastError();
               if (error != WSAEWOULDBLOCK) {
                  cleanup(true);
               }
            }
            else if (len != sendBuf.size()) {
               //partial read, so shift remainder of buffer to front
               shift(sendBuf, (uint32_t)len);
               //msg(PLUGIN_NAME": wrote: %d bytes \n", len);
            }
            else {
               //entire buffer was sent, so clear the buffer
               sendBuf.reset();
               //msg(PLUGIN_NAME": wrote: %d bytes \n", len);
            }
            break;
         }
         case FD_CLOSE:  //server connection closed.
            cleanup(true);
            msg(PLUGIN_NAME": connection to server severed at FD_CLOSE.\n");
            break;
      }
   }
   return FALSE;
}
示例#3
0
//does the buffer contain a complete data packet?
bool isComplete(Buffer &b) {
   int rs = requiredSize(b);
   return rs > 0 && b.size() >= rs;
}
void MScalableImagePrivate::drawScalable9(qreal x, qreal y, qreal w, qreal h, QPainter *painter) const
{
    QMargins margins = m_preferredMargins;

    if (w == -1 )
        w = m_image->width();
    if (h == -1 )
        h = m_image->height();

    int cornerWidth = 0;
    int cornerHeight = 0;
    if (m_imageType == MScalable9 ) {
        cornerWidth = margins.left() + margins.right();
        cornerHeight = margins.top() + margins.bottom();
    }

    //Make sure that the size of the drawn image is
    //bigger than the 4 corner blocks. If necessary,
    //use smaller border values than those set with setBorders API
    //call.
    if (w <= cornerWidth) {
        margins.setLeft(qMax((qreal)0.0, margins.left() - (cornerWidth - w + 1) / 2));
        margins.setRight(qMax((qreal)0.0, margins.right() - (cornerWidth - w + 1) / 2));
    }
    if (h <= cornerHeight) {
        margins.setTop(qMax((qreal)0.0, margins.top() - (cornerHeight - h + 1) / 2));
        margins.setBottom(qMax((qreal)0.0, margins.bottom() - (cornerHeight - h + 1) / 2));
    }

    if (w <= 0 || h <= 0) {
        // this should really not happen
        mWarning("MScalableImage") <<
                                   "Received request to draw pixmap of invalid size" << w << "x" << h;
        return;
    }

    //the image is used in its native size
    //no need to scale just draw it
    QSize requiredSize(w, h);
    if (m_image->size() == requiredSize) {
        painter->drawPixmap(x, y, *m_image);
        return;
    }
    else {
#if QT_VERSION < QT_VERSION_CHECK(4,8,0)
        //There is a known bug in Qt 4.7 qDrawBorderPixmap/QPainter which
        //can cause graphical glitches if the chosen borders result in
        //zero-sized blocks on the image, so as a workaround the borders
        //must be altered to prevent that in cases where rendering is done
        //using qDrawBorderPixmap.
        if (margins.top() == 0)
            margins.setTop(1);
        if (margins.left() == 0)
            margins.setLeft(1);

        if (margins.bottom() == 0)
            margins.setBottom(1);
        if (margins.right() == 0)
            margins.setRight(1);
#endif

#ifdef __arm__
        if (!downscaleWarningPrinted && (w < m_image->size().width() || h < m_image->size().height()))
            outputDownscaleWarning("MScalableImage9", w, h);
        else if(!nearscaleWarningPrinted && qAbs(m_image->size().width()/w-1.0) < SCALE_WARN_LIMIT && qAbs(m_image->size().height()/h-1.0) < SCALE_WARN_LIMIT)
            outputNearscaleWarning("MScalableImage9", w, h);
        qDrawBorderPixmap(painter, QRect(x, y, w, h), margins, *m_image, m_image->rect(), margins, tileRules);
#else
        //the image doesn't fit directly into the required size.
        //check whether or not we're allowed to cache
        bool docache = painter->paintEngine()->type() != QPaintEngine::OpenGL
                       && painter->paintEngine()->type() != QPaintEngine::OpenGL2;

        if (docache) {
            //software rendering is not fast when scaling pixmaps, so we use the
            //global pixmap cache to avoid rescaling more than needed.
            //
            //TODO: this cache gets thrashed a bit with widgetsgallery, may want to look into possibly
            //increasing the size of QPixmapCache.
            QString key = QString("msi-%1-%2,%3").arg((*m_image).cacheKey()).arg(w).arg(h);
            QPixmap scaled;
            if (QPixmapCache::find(key, &scaled)) {
                //cached! draw and we're done
                painter->drawPixmap(x, y, scaled);
                return;
            }

            // draw into cache
            scaled = QPixmap(requiredSize);
            scaled.fill(Qt::transparent);
            QPainter p;
            if (p.begin(&scaled)) {
                p.setRenderHint(QPainter::SmoothPixmapTransform);
                qDrawBorderPixmap(&p, QRect(0, 0, w, h), margins, *m_image, m_image->rect(), margins, tileRules);
                p.end();
            }

            // draw to screen
            painter->drawPixmap(x, y, scaled);
            QPixmapCache::insert(key, scaled);

            // remember the key so that the entry can be removed on-demand
            const_cast<MScalableImagePrivate*>(this)->cachedImageKey = key;
        } else {
            if (!downscaleWarningPrinted && (w < m_image->size().width() || h < m_image->size().height()))
                outputDownscaleWarning("MScalableImage9", w, h);
            else if(!nearscaleWarningPrinted && qAbs(m_image->size().width()/w-1.0) < SCALE_WARN_LIMIT && qAbs(m_image->size().height()/h-1.0) < SCALE_WARN_LIMIT)
                outputNearscaleWarning("MScalableImage9", w, h);
            // caching isn't permitted for this case; scale and render direct to screen.
            qDrawBorderPixmap(painter, QRect(x, y, w, h), margins, *m_image, m_image->rect(), margins, tileRules);

            if (!cachedImageKey.isEmpty()) {
                QPixmapCache::remove(cachedImageKey);
                const_cast<MScalableImagePrivate*>(this)->cachedImageKey.clear();
            }
        }
#endif // __arm__
    }
}